| ÐокÑменÑаÑÐ¸Ñ Ð¿Ð¾ PostgreSQL 9.4.1 | |||
|---|---|---|---|
| ÐÑед. | УÑÐ¾Ð²ÐµÐ½Ñ Ð²ÑÑе | Ðлава 43. PL/Python â пÑоÑедÑÑнÑй ÑзÑк Python | След. |
43.3. ÐнаÑÐµÐ½Ð¸Ñ Ð´Ð°Ð½Ð½ÑÑ
ÐообÑе говоÑÑ, ÑÐµÐ»Ñ Ð¸ÑполниÑÐµÐ»Ñ PL/Python â обеÑпеÑиÑÑ "еÑÑеÑÑвенное" ÑооÑвеÑÑÑвие Ð¼ÐµÐ¶Ð´Ñ Ð¼Ð¸Ñами PostgreSQL и Python. ÐÑим обÑÑÑнÑеÑÑÑ Ð²ÑÐ±Ð¾Ñ Ð¿Ñавил ÑопоÑÑÐ°Ð²Ð»ÐµÐ½Ð¸Ñ Ð´Ð°Ð½Ð½ÑÑ , опиÑаннÑÑ Ð½Ð¸Ð¶Ðµ.
43.3.1. СопоÑÑавление Ñипов даннÑÑ
ÐÑгÑменÑÑ ÑÑнкÑий пÑеобÑазÑÑÑÑÑ Ð¸Ð· Ñипа PostgreSQL в ÑооÑвеÑÑÑвÑÑÑий Ñип Python по Ñаким пÑавилам:
Тип PostgreSQL boolean пÑеобÑазÑеÑÑÑ Ð² bool ÑзÑка Python.
Ð¢Ð¸Ð¿Ñ PostgreSQL smallint и int пÑеобÑазÑÑÑÑÑ Ð² Ñип int ÑзÑка Python. Ð¢Ð¸Ð¿Ñ PostgreSQL bigint и oid ÑÑановÑÑÑÑ Ñипами long в Python 2 и int в Python 3.
Ð¢Ð¸Ð¿Ñ PostgreSQL real и double пÑеобÑазÑÑÑÑÑ Ð² Ñип float ÑзÑка Python.
Тип PostgreSQL numeric пÑеобÑазÑеÑÑÑ Ð² Decimal ÑÑÐµÐ´Ñ Python. ÐÑÐ¾Ñ Ñип импоÑÑиÑÑеÑÑÑ Ð¸Ð· пакеÑа cdecimal, пÑи его налиÑии. РпÑоÑивном ÑлÑÑае иÑполÑзÑеÑÑÑ decimal.Decimal из ÑÑандаÑÑной библиоÑеки. Тип cdecimal ÑабоÑÐ°ÐµÑ Ð·Ð½Ð°ÑиÑелÑно бÑÑÑÑее, Ñем decimal. Ðднако в Python 3.3 Ñип cdecimal бÑл вклÑÑÑн в ÑÑандаÑÑнÑÑ Ð±Ð¸Ð±Ð»Ð¸Ð¾ÑÐµÐºÑ Ð¿Ð¾Ð´ именем decimal, Ñак ÑÑо ÑепеÑÑ ÑÑого ÑазлиÑÐ¸Ñ Ð½ÐµÑ.
Тип PostgreSQL bytea ÑÑановиÑÑÑ Ñипом str в Python 2 и bytes в Python 3. Ð Python 2 ÑакÑÑ ÑÑÑÐ¾ÐºÑ ÑледÑÐµÑ Ð²Ð¾ÑпÑинимаÑÑ ÐºÐ°Ðº поÑледоваÑелÑноÑÑÑ Ð±Ð°Ð¹Ñ Ð±ÐµÐ· какой-либо опÑеделÑнной кодиÑовки Ñимволов.
ÐÑе дÑÑгие ÑÐ¸Ð¿Ñ Ð´Ð°Ð½Ð½ÑÑ , вклÑÑÐ°Ñ ÑÐ¸Ð¿Ñ ÑимволÑнÑÑ ÑÑÑок PostgreSQL, пÑеобÑазÑÑÑÑÑ Ð² Ñип str ÑзÑка Python. Ð Python 2 ÑÑа ÑÑÑока бÑÐ´ÐµÑ Ð¿ÐµÑедаваÑÑÑÑ Ð² кодиÑовке ÑеÑвеÑа PostgreSQL; в Python 3 ÑÑо бÑÐ´ÐµÑ ÑÑÑока в Unicode, как и вÑе ÑÑÑоки.
ÐнÑоÑмаÑÐ¸Ñ Ð¾ неÑкалÑÑнÑÑ ÑÐ¸Ð¿Ð°Ñ Ð´Ð°Ð½Ð½ÑÑ Ð¿Ñиведена ниже.
ÐнаÑениÑ, возвÑаÑаемÑе ÑÑнкÑией, пÑеобÑазÑÑÑÑÑ Ð² Ñип даннÑÑ , обÑÑвленнÑй как Ñип ÑезÑлÑÑаÑа в PostgreSQL, ÑледÑÑÑим обÑазом:
Ðогда Ñип ÑезÑлÑÑаÑа ÑÑнкÑии в PostgreSQL â boolean, возвÑаÑаемое знаÑение пÑиводиÑÑÑ Ðº логиÑеÑÐºÐ¾Ð¼Ñ ÑÐ¸Ð¿Ñ Ð¿Ð¾ пÑавилам, пÑинÑÑÑм в Python. То еÑÑÑ false бÑÐ´ÐµÑ Ð²Ð¾Ð·Ð²ÑаÑено Ð´Ð»Ñ 0 и пÑÑÑой ÑÑÑоки, но, обÑаÑиÑе внимание, Ð´Ð»Ñ 'f' бÑÐ´ÐµÑ Ð²Ð¾Ð·Ð²ÑаÑено true.
Ðогда Ñип ÑезÑлÑÑаÑа ÑÑнкÑии PostgreSQL â bytea, возвÑаÑаемое знаÑение бÑÐ´ÐµÑ Ð¿ÑеобÑазовано в ÑÑÑÐ¾ÐºÑ (Python 2) или Ð½Ð°Ð±Ð¾Ñ Ð±Ð°Ð¹Ñ (Python 3), иÑполÑзÑÑ Ð²ÑÑÑоеннÑе ÑÑедÑÑва Python, а заÑем бÑÐ´ÐµÑ Ð¿Ñиведено к ÑÐ¸Ð¿Ñ bytea.
ÐÐ»Ñ Ð²ÑÐµÑ Ð´ÑÑÐ³Ð¸Ñ Ñипов ÑезÑлÑÑаÑа PostgreSQL возвÑаÑаемое знаÑение Python пÑеобÑазÑеÑÑÑ Ð² ÑÑÑÐ¾ÐºÑ Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ Ð²ÑÑÑоенной в Python ÑÑнкÑии str, и полÑÑÐµÐ½Ð½Ð°Ñ ÑÑÑока пеÑедаÑÑÑÑ ÑÑнкÑии ввода Ñипа даннÑÑ PostgreSQL.
Ð Python 2, ÑÑÑоки Ð´Ð¾Ð»Ð¶Ð½Ñ Ð¿ÐµÑедаваÑÑÑÑ Ð² PostgreSQL в кодиÑовке ÑеÑвеÑа PostgreSQL. ÐÑи пеÑедаÑе ÑÑÑоки, непÑиемлемой Ð´Ð»Ñ ÑекÑÑей кодиÑовки ÑеÑвеÑа, Ð²Ð¾Ð·Ð½Ð¸ÐºÐ°ÐµÑ Ð¾Ñибка, но не вÑе неÑооÑвеÑÑÑÐ²Ð¸Ñ ÐºÐ¾Ð´Ð¸Ñовки могÑÑ Ð±ÑÑÑ Ð²ÑÑвленÑ, Ñак ÑÑо Ñ Ð½ÐµÐºÐ¾ÑÑекÑной кодиÑовкой вÑÑ Ð¶Ðµ могÑÑ Ð±ÑÑÑ Ð¿Ð¾Ð»ÑÑÐµÐ½Ñ Ð½ÐµÑиÑаемÑе ÑÑÑоки. СÑÑоки Unicode пеÑеводÑÑÑÑ Ð² нÑжнÑÑ ÐºÐ¾Ð´Ð¸ÑÐ¾Ð²ÐºÑ Ð°Ð²ÑомаÑиÑеÑки, Ñак ÑÑо иÑполÑзоваÑÑ Ð¸Ñ Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð±ÐµÐ·Ð¾Ð¿Ð°Ñнее и Ñдобнее. Ð Python 3 вÑе ÑÑÑоки имеÑÑ ÐºÐ¾Ð´Ð¸ÑÐ¾Ð²ÐºÑ Unicode.
ÐнÑоÑмаÑÐ¸Ñ Ð¾ неÑкалÑÑнÑÑ ÑÐ¸Ð¿Ð°Ñ Ð´Ð°Ð½Ð½ÑÑ Ð¿Ñиведена ниже.
ÐбÑаÑиÑе внимание, ÑÑо логиÑеÑкие неÑооÑвеÑÑÑÐ²Ð¸Ñ Ð¼ÐµÐ¶Ð´Ñ Ð¾Ð±ÑÑвленнÑм в PostgreSQL Ñипом ÑезÑлÑÑаÑа и Ñипом Python ÑакÑиÑеÑкого возвÑаÑаемого обÑекÑа игноÑиÑÑÑÑÑÑ â знаÑение пÑеобÑазÑеÑÑÑ Ð² лÑбом ÑлÑÑае.
43.3.2. Null, None
ÐÑли ÑÑнкÑии пеÑедаÑÑÑÑ Ð·Ð½Ð°Ñение SQL NULL, в Python знаÑением ÑÑого аÑгÑменÑа бÑÐ´ÐµÑ None. ÐапÑимеÑ, ÑÑнкÑÐ¸Ñ pymax, опÑеделÑÐ½Ð½Ð°Ñ ÐºÐ°Ðº показано в Раздел 43.2, возвÑаÑÐ¸Ñ Ð½ÐµÐ²ÐµÑнÑй оÑвеÑ, полÑÑив аÑгÑменÑÑ NULL. ÐÑ Ð¼Ð¾Ð³Ð»Ð¸ Ð±Ñ Ð´Ð¾Ð±Ð°Ð²Ð¸ÑÑ Ñказание STRICT в опÑеделение ÑÑнкÑии, ÑÑÐ¾Ð±Ñ PostgreSQL поÑÑÑпал немного ÑазÑмнее: пÑи пеÑедаÑе знаÑÐµÐ½Ð¸Ñ NULL ÑÑнкÑÐ¸Ñ Ð²Ð¾Ð²Ñе не бÑÐ´ÐµÑ Ð²ÑзÑваÑÑÑÑ, бÑÐ´ÐµÑ ÑÑÐ°Ð·Ñ Ð²Ð¾Ð·Ð²ÑаÑÑн ÑезÑлÑÑÐ°Ñ NULL. С дÑÑгой ÑÑоÑонÑ, Ð¼Ñ Ð¼Ð¾Ð³Ð»Ð¸ Ð±Ñ Ð¿ÑовеÑиÑÑ Ð°ÑгÑменÑÑ Ð½Ð° NULL в Ñеле ÑÑнкÑии:
CREATE FUNCTION pymax (a integer, b integer)
RETURNS integer
AS $$
if (a is None) or (b is None):
return None
if a > b:
return a
return b
$$ LANGUAGE plpythonu;Ðак показано вÑÑе, ÑÑÐ¾Ð±Ñ Ð²ÑдаÑÑ Ð¸Ð· ÑÑнкÑии PL/Python знаÑение SQL NULL, нÑжно веÑнÑÑÑ Ð·Ð½Ð°Ñение None. ÐÑо можно ÑделаÑÑ Ð¸ в ÑÑÑогой, и в неÑÑÑогой ÑÑнкÑии.
43.3.3. ÐаÑÑивÑ, ÑпиÑки
ÐнаÑÐµÐ½Ð¸Ñ Ð¼Ð°ÑÑивов SQL пеÑедаÑÑÑÑ Ð² PL/Python в виде ÑпиÑка Python. ЧÑÐ¾Ð±Ñ Ð²ÐµÑнÑÑÑ Ð¼Ð°ÑÑив SQL из ÑÑнкÑии PL/Python, возвÑаÑиÑе поÑледоваÑелÑноÑÑÑ Python, напÑимеÑ, ÑпиÑок или коÑÑеж:
CREATE FUNCTION return_arr()
RETURNS int[]
AS $$
return (1, 2, 3, 4, 5)
$$ LANGUAGE plpythonu;
SELECT return_arr();
return_arr
-------------
{1,2,3,4,5}
(1 row)УÑÑиÑе, ÑÑо в Python и ÑÑÑоки ÑвлÑÑÑÑÑ Ð¿Ð¾ÑледоваÑелÑноÑÑÑми, ÑÑо Ð¼Ð¾Ð¶ÐµÑ Ð´Ð°Ð²Ð°ÑÑ Ð½ÐµÐ¾Ð¶Ð¸Ð´Ð°Ð½Ð½Ñе ÑÑÑекÑÑ, Ñ Ð¾ÑоÑо знакомÑе Ñем, кÑо пÑогÑаммиÑÑÐµÑ Ð½Ð° Python:
CREATE FUNCTION return_str_arr()
RETURNS varchar[]
AS $$
return "hello"
$$ LANGUAGE plpythonu;
SELECT return_str_arr();
return_str_arr
----------------
{h,e,l,l,o}
(1 row)43.3.4. СоÑÑавнÑе ÑипÑ
ÐÑгÑменÑÑ ÑоÑÑавного Ñипа пеÑедаÑÑÑÑ ÑÑнкÑии в виде ÑопоÑÑавлений Python. Ðменами ÑлеменÑов ÑопоÑÑÐ°Ð²Ð»ÐµÐ½Ð¸Ñ ÑвлÑÑÑÑÑ Ð°ÑÑибÑÑÑ ÑоÑÑавного Ñипа. ÐÑли аÑÑибÑÑ Ð² пеÑеданной ÑÑÑоке Ð¸Ð¼ÐµÐµÑ Ð·Ð½Ð°Ñение NULL, он пеÑедаÑÑÑÑ Ð² ÑопоÑÑавлении знаÑением None. ÐÑÐ¸Ð¼ÐµÑ ÑабоÑÑ Ñ ÑоÑÑавнÑм Ñипом:
CREATE TABLE employee (
name text,
salary integer,
age integer
);
CREATE FUNCTION overpaid (e employee)
RETURNS boolean
AS $$
if e["salary"] > 200000:
return True
if (e["age"] < 30) and (e["salary"] > 100000):
return True
return False
$$ LANGUAGE plpythonu;ÐозвÑаÑиÑÑ ÑоÑÑавной Ñип или ÑÑÑÐ¾ÐºÑ ÑаблиÑÑ Ð¸Ð· ÑÑнкÑии Python можно неÑколÑкими ÑпоÑобами. Ð ÑледÑÑÑÐ¸Ñ Ð¿ÑимеÑÐ°Ñ Ð¿ÑедполагаеÑÑÑ, ÑÑо Ñ Ð½Ð°Ñ Ð¾Ð±ÑÑвлен Ñип:
CREATE TYPE named_value AS ( name text, value integer );
РезÑлÑÑÐ°Ñ ÑÑого Ñипа можно веÑнÑÑÑ ÐºÐ°Ðº:
- ÐоÑледоваÑелÑноÑÑÑ (коÑÑеж или ÑпиÑок, но не множеÑÑво, Ñак как оно не индекÑиÑÑеÑÑÑ)
РвозвÑаÑаемÑÑ Ð¾Ð±ÑекÑÐ°Ñ Ð¿Ð¾ÑледоваÑелÑноÑÑей должно бÑÑÑ ÑÑолÑко ÑлеменÑов, ÑколÑко полей в ÑоÑÑавном Ñипе ÑезÑлÑÑаÑа. ÐÐ»ÐµÐ¼ÐµÐ½Ñ Ñ Ð¸Ð½Ð´ÐµÐºÑом 0 пÑиÑваиваеÑÑÑ Ð¿ÐµÑÐ²Ð¾Ð¼Ñ Ð¿Ð¾Ð»Ñ ÑоÑÑавного Ñипа, Ñ Ð¸Ð½Ð´ÐµÐºÑом 1 â вÑоÑÐ¾Ð¼Ñ Ð¸ Ñ. д. ÐапÑимеÑ:
CREATE FUNCTION make_pair (name text, value integer) RETURNS named_value AS $$ return [ name, value ] # или в виде коÑÑежа: return ( name, value ) $$ LANGUAGE plpythonu;
ЧÑÐ¾Ð±Ñ Ð²ÑдаÑÑ SQL NULL Ð´Ð»Ñ ÐºÐ°ÐºÐ¾Ð¹-нибÑÐ´Ñ ÐºÐ¾Ð»Ð¾Ð½ÐºÐ¸, вÑÑавÑÑе в ÑооÑвеÑÑÑвÑÑÑÑÑ Ð¿Ð¾Ð·Ð¸ÑÐ¸Ñ None.
- СопоÑÑавление (ÑловаÑÑ)
ÐнаÑение колонки ÑезÑлÑÑаÑа полÑÑаеÑÑÑ Ð¸Ð· ÑопоÑÑавлениÑ, в коÑоÑом клÑÑом ÑвлÑеÑÑÑ Ð¸Ð¼Ñ ÐºÐ¾Ð»Ð¾Ð½ÐºÐ¸. ÐапÑимеÑ:
CREATE FUNCTION make_pair (name text, value integer) RETURNS named_value AS $$ return { "name": name, "value": value } $$ LANGUAGE plpythonu;ÐÑбÑе дополниÑелÑнÑе паÑÑ ÐºÐ»ÑÑ/знаÑение в ÑловаÑе игноÑиÑÑÑÑÑÑ, а оÑÑÑÑÑÑвие нÑжнÑÑ ÐºÐ»ÑÑей ÑÑиÑаеÑÑÑ Ð¾Ñибкой. ЧÑÐ¾Ð±Ñ Ð²ÑдаÑÑ SQL NULL Ð´Ð»Ñ ÐºÐ°ÐºÐ¾Ð¹-нибÑÐ´Ñ ÐºÐ¾Ð»Ð¾Ð½ÐºÐ¸, вÑÑавÑÑе None Ñ Ð¸Ð¼ÐµÐ½ÐµÐ¼ ÑооÑвеÑÑÑвÑÑÑей колонки в каÑеÑÑве клÑÑа.
- ÐбÑÐµÐºÑ (лÑбой обÑÐµÐºÑ Ñ Ð¼ÐµÑодом __getattr__)
ÐбÑÐµÐºÑ Ð¿ÐµÑедаÑÑÑÑ Ð°Ð½Ð°Ð»Ð¾Ð³Ð¸Ñно ÑопоÑÑавлениÑ. ÐÑимеÑ:
CREATE FUNCTION make_pair (name text, value integer) RETURNS named_value AS $$ class named_value: def __init__ (self, n, v): self.name = n self.value = v return named_value(name, value) # или пÑоÑÑо class nv: pass nv.name = name nv.value = value return nv $$ LANGUAGE plpythonu;
Также поддеÑживаÑÑÑÑ ÑÑнкÑии Ñ Ð¿Ð°ÑамеÑÑами OUT (вÑÑ Ð¾Ð´Ð½Ñми). ÐапÑимеÑ:
CREATE FUNCTION multiout_simple(OUT i integer, OUT j integer) AS $$ return (1, 2) $$ LANGUAGE plpythonu; SELECT * FROM multiout_simple();
43.3.5. ФÑнкÑии, возвÑаÑаÑÑие множеÑÑва
ФÑнкÑÐ¸Ñ PL/Python Ñакже Ð¼Ð¾Ð¶ÐµÑ Ð²Ð¾Ð·Ð²ÑаÑаÑÑ Ð¼Ð½Ð¾Ð¶ÐµÑÑва, ÑодеÑжаÑие ÑкалÑÑнÑе и ÑоÑÑавнÑе ÑипÑ. ÐÑо можно оÑÑÑеÑÑвиÑÑ ÑазнÑми ÑпоÑобами, Ñак как возвÑаÑаемÑй обÑÐµÐºÑ Ð²Ð½ÑÑÑи пÑевÑаÑаеÑÑÑ Ð² иÑеÑаÑоÑ. Ð ÑледÑÑÑÐ¸Ñ Ð¿ÑимеÑÐ°Ñ Ð¿ÑедполагаеÑÑÑ, ÑÑо Ñ Ð½Ð°Ñ ÐµÑÑÑ ÑоÑÑавной Ñип:
CREATE TYPE greeting AS ( how text, who text );
ÐножеÑÑво в каÑеÑÑве ÑезÑлÑÑаÑа можно возвÑаÑиÑÑ, пÑименив:
- ÐоÑледоваÑелÑноÑÑÑ (коÑÑеж, ÑпиÑок, множеÑÑво)
CREATE FUNCTION greet (how text) RETURNS SETOF greeting AS $$ # возвÑаÑÐ°ÐµÑ ÐºÐ¾ÑÑеж, ÑодеÑжаÑий ÑпиÑки в каÑеÑÑве ÑоÑÑавнÑÑ Ñипов # Ñакже бÑдÑÑ ÑабоÑаÑÑ Ð¸ оÑÑалÑнÑе комбинаÑии return ( [ how, "World" ], [ how, "PostgreSQL" ], [ how, "PL/Python" ] ) $$ LANGUAGE plpythonu;
- ÐÑеÑаÑÐ¾Ñ (лÑбой обÑекÑ, ÑеализÑÑÑий меÑÐ¾Ð´Ñ __iter__ и next)
CREATE FUNCTION greet (how text) RETURNS SETOF greeting AS $$ class producer: def __init__ (self, how, who): self.how = how self.who = who self.ndx = -1 def __iter__ (self): return self def next (self): self.ndx += 1 if self.ndx == len(self.who): raise StopIteration return ( self.how, self.who[self.ndx] ) return producer(how, [ "World", "PostgreSQL", "PL/Python" ]) $$ LANGUAGE plpythonu;- ÐенеÑаÑÐ¾Ñ (yield)
CREATE FUNCTION greet (how text) RETURNS SETOF greeting AS $$ for who in [ "World", "PostgreSQL", "PL/Python" ]: yield ( how, who ) $$ LANGUAGE plpythonu;Ðнимание Ðз-за оÑибки 1483133 в Python, некоÑоÑÑе оÑладоÑнÑе веÑÑии Python 2.4 (ÑконÑигÑÑиÑованнÑе и ÑкомпилиÑованнÑе Ñ ÐºÐ»ÑÑом --with-pydebug) вÑводÑÑ Ð¸Ð· ÑÑÑÐ¾Ñ ÑеÑÐ²ÐµÑ PostgreSQL, когда иÑеÑаÑÐ¾Ñ Ð²Ð¾Ð·Ð²ÑаÑÐ°ÐµÑ Ð½Ð°Ð±Ð¾Ñ ÑезÑлÑÑаÑов. ÐÑа оÑибка пÑоÑвлÑеÑÑÑ Ð² неиÑпÑавленнÑÑ Ð²ÐµÑÑиÑÑ Fedora 4, но не в вÑпÑÑкаемÑÑ Ð²ÐµÑÑиÑÑ Python и в иÑпÑавленной Fedora 4.
Также поддеÑживаÑÑÑÑ ÑÑнкÑии, возвÑаÑаÑÑие множеÑÑва, Ñ Ð¿Ð°ÑамеÑÑами OUT (обÑÑвленнÑе Ñ RETURNS SETOF record). ÐапÑимеÑ:
CREATE FUNCTION multiout_simple_setof(n integer, OUT integer, OUT integer) RETURNS SETOF record AS $$ return [(1, 2)] * n $$ LANGUAGE plpythonu; SELECT * FROM multiout_simple_setof(3);
| ÐÑед. | ÐаÑало | След. |
| ФÑнкÑии на PL/Python | УÑÐ¾Ð²ÐµÐ½Ñ Ð²ÑÑе | СовмеÑÑное иÑполÑзование даннÑÑ |