Здравствуйте. Есть такая хранимая функция:
Python
CREATE OR REPLACE FUNCTION save_order(id integer, ordernumber text,
orderdate date, warrant text, notes text, purpose text, obj text, contragent_id integer, representator_id integer,
registrator_id integer)
RETURNS save_result AS
$$
plan = plpy.prepare("""SELECT
insert_into_classifier($1, $2, $3, $4) as id""",
['text', 'text', 'text', 'text'])
rows = plpy.execute(plan, ['purposes', 'id', 'name', purpose], 1)
purpose_id = rows[0]['id']
rows = plpy.execute(plan, ['obj_types', 'id', 'name', obj], 1)
obj_type_id = rows[0]['id']
if len(ordernumber) == 0:
#Generate a new number
rows = plpy.execute("""SELECT MAX("date") as max_date
FROM orders""", 1)
import datetime
md = rows[0]['max_date']
cd = datetime.datetime.now()
if md.year < cd.year:
#Set the counter to 1
plpy.execute('ALTER SEQUENCE orders_number_seq RESTART WITH 1')
rows = plpy.execute("""SELECT nextval('orders_number_seq') as newNum""", 1)
ordernumber = "{year}/{num}".format(year=cd.year, num=rows[0]['newNum'])
if not id or id == 0:
plan = plpy.prepare("""INSERT INTO orders ("number", "date", warrant,
notes, purpose_id, registrator_id, contragent_id, representator_id, obj_type_id)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)""",
['text', 'date', 'text', 'text', 'integer', 'integer', 'integer', 'integer',
'integer'])
plpy.execute(plan, [ordernumber, orderdate, warrant, notes, purpose_id, registrator_id,
contragent_id, representator_id, obj_type_id])
action = "INSERT"
rows = plpy.execute("SELECT lastval() as id", 1)
id = rows[0]['id']
else:
plan = plpy.prepare("""UPDATE orders SET "number" = $1, "date" = $2, warrant = $3,
notes = $4, purpose_id = $5, registrator_id = $6, contragent_id = $7,
representator_id = $8, obj_type_id = $9 WHERE id = $10""",
['text', 'date', 'text', 'text', 'integer', 'integer', 'integer', 'integer',
'integer', 'integer'])
plpy.execute(plan, [ordernumber, orderdate, warrant, notes, purpose_id, registrator_id,
contragent_id, representator_id, obj_type_id, id])
action = "UPDATE"
return (id, action, "OK", ordernumber, "", "")
$$
LANGUAGE plpython3u;
Не хочет работать. При вызове из клиентской части валит исключение
psycopg2.InternalError: UnboundLocalError: local variable 'ordernumber' referenced before assignment
CONTEXT: Traceback (most recent call last):
PL/Python function "save_order", line 10, in <module>
if len(ordernumber) == 0:
PL/Python function "save_order"
Это значит, что переменная ordernumber
не объявлена (переменная используется до назначения ей какого-либо значения).
С чего бы это? Ведь в определении функции она есть и остальные переменные до её использования нормально находились в контексте.
Пофиг, написал
Python
global ordernumber
и... Всё заработало. Причём как заработало. Теперь начал ругаться на строчку "if not id or id == 0:", что типа нет такой переменной id. Тоже дописал global и завелось. Самое удивительное, что остальные переменные не пришлось так объявлять. В чём же соль?