我写了一个函数将记录插入表person
。行ID是串行(自动递增)如何通过调用Postgres函数插入记录时提交
CREATE OR REPLACE FUNCTION public.add_person(
name character varying,
email character varying,
level integer,
company_id integer,
comp_list integer[])
RETURNS integer as
$BODY$
declare
p_id integer;
begin
insert into person (name, email, level, company_id, comp_list, status, insert_ts) values ($1, $2, $3, $4, $5, 'Y', now())
returning person.person_id into p_id;
return p_id;
end
$BODY$ LANGUAGE 'plpgsql'
如果我运行SQL select * from add_person('xxx', '[email protected]', 1, 3, '{1,2}')
这个功能,它成功地插入一条记录。但是,当我使用SQLAlchemy在Python中调用此函数时,无法插入记录。
engine = create_engine(URL(**settings.DATABASE))
session = scoped_session(sessionmaker(bind=engine))
email = '[email protected]'
company = 1
level = 3
comp_list = '1,2'
args = "'', '" + email + "', " + str(company) + ", " + str(level) + ", '{" + comp_list + "}'"
statement = "select * from add_person({})".format(args)
session.execute(statement)
在Python中构造的语句与我在postgres中运行的命令完全相同。但它并没有像表中那样插入记录。根本没有错误信息。 session
,engine
配置正确,因为所有其他select
查询工作。
我也注意到,即使记录不能使用python代码插入。主键的顺序确实增加了。因为当我在postgres中再次运行函数时,行ID跳过了。
如果我用SQLAlchemy会话进行插入而没有提交,行为是一样的。
def add_person(name, email, company, level, comp_list):
current_ts = datetime.datetime.now()
p = Person(name = name,
email = email,
company_id = company,
level = level,
comp_list = comp_list,
status = 'Y',
insert_ts = current_ts)
session.add(p)
session.flush()
return p.person_id
如果我运行上述方法的Python,person_id
增量但没有记录被插入。只有当我将session.flush
更改为以下时,记录才能正确插入。
session.add(p)
session.commit()
session.refresh(p)
print(p.person_id)
return p.person_id
调用plsql函数时提交插入操作的正确方法是什么?
尝试'conn.autocommit = True'请参阅[事务控制。](http://initd.org/psycopg/docs/usage.html#transactions-control) – klin
请*不要使用字符串格式*来传递值查询。这就是占位符/绑定对象的用途。阅读http://docs.sqlalchemy.org/en/latest/core/tutorial.html#using-textual-sql查看“how”和https://xkcd.com/327/查看“why”。 –
这里甚至不需要文本SQL。函数泛型允许你执行'func.add_person('',email,company,level,comp_list.split(','))。select())'。请注意,您可以并应该将comp_list作为一个列表。 –