我有以下带有2个插入语句的PosgreSQL函数:
CREATE OR REPLACE FUNCTION create_user(
_username character varying,
_email character varying,
_password character varying,
_first_name character varying,
_middle_initial character,
_last_name character varying,
_title character varying,
_enabled boolean,
_company_id integer,
_created_by integer,
_superuser boolean)
RETURNS UserAccount AS
$BODY$DECLARE
result UserAccount;
BEGIN
INSERT INTO UserAccount
(username, email, password, first_name, middle_initial,
last_name, title, enabled, created_by, superuser)
VALUES (_username, _email, _password, _first_name,_middle_initial,
_last_name, _title, _enabled, _created_by, _superuser)
RETURNING * INTO result;
INSERT INTO UserCompany (user_id, company_id)
VALUES (result.id, _company_id);
RETURN result;
END;$BODY$
LANGUAGE plpgsql VOLATILE STRICT;
通过PGAdmin执行SELECT * FROM create_user(..._)
按预期工作并返回新的UserAccount行。
我的Python代码如下:
conn = psycopg2.connect(app.config.get('POSTGRES_URI'))
cursor = conn.cursor()
# Some prep of variables...
cursor.execute("""
SELECT
id, username, email, first_name, middle_initial, last_name, last_login, title, failed_attempts, enabled, created_by, superuser
FROM create_user(%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)""", (
username, email, str(hashed_password), first_name, middle_initial, last_name,
title, enabled, company_id, created_by, superuser
))
conn.commit()
user = dict(zip([x[0] for x in g.db.description], g.db.fetchone()))
cursor.close()
conn.close()
return user
这将返回值的所有空值,而不是提交插入。如果我从函数中删除第二个INSERT语句,它将按预期工作。我尝试了conn.autocommit = True
,conn.set_isolation_level(0)
,并使用了cursor.callproc(...)方法。仍然不起作用。我现在错过了什么,或者这是psycopg2的问题吗?
编辑 - 解决方案(facepalm):
我发现问题是函数的STRICT子句。与pscyopg2无关。感觉现在问这个问题。我正在向函数传递一个空值,当然,这是当传递空值时STRICT应该做什么......没有。
答案 0 :(得分:0)
您不应该在Python脚本中提交您的select语句。提交应该在您的PosgreSQL函数中进行。尝试抛出一个提交;在RETURN线以上。
答案 1 :(得分:0)
解决方案(facepalm):
我发现问题是函数的STRICT子句。与pscyopg2无关。感觉现在问这个问题。我正在向函数传递一个空值,当然,这是当传递空值时STRICT应该做什么......没有。
答案 2 :(得分:0)
适合我:
create table UserAccount (
id serial primary key, username text
);
create table UserCompany (
user_id integer primary key,
company_id integer
);
create or replace function create_user(
_username character varying,
_company_id integer
) returns UserAccount as $body$
declare
result UserAccount;
begin
insert into UserAccount (username)
values (_username)
returning * into result;
insert into UserCompany (user_id, company_id)
values (result.id, _company_id);
return result;
end;
$body$ language plpgsql volatile strict;
Python代码
from psycopg2 import connect
con = connect('dbname=cpn')
curs = con.cursor()
curs.execute('''
select * from create_user(%s, %s);
''', ('john', 2))
con.commit()
user = curs.fetchone()
print user
con.close()
返回
(2, 'john')