所以我对使用SQLAlchemy和PostgreSQL的这种奇怪行为感到非常困惑。假设我有一张桌子:
create table staging.my_table(
id integer DEFAULT nextval(...),
name text,
...
);
和一个存储的函数:
create or replace function staging.test()
returns void
language plpgsql
as $function$
begin
insert into staging.my_table (name) values ('yay insert');
end;
$function$;
我现在想做的是使用SQLAlchemy在Python中调用此函数,如下所示:
from sqlalchemy import create_engine
engine = create_engine('postgresql+psycopg2://foo:bar@localhost:5432/baz')
engine.execute('select staging.test()')
当我运行此Python代码时,数据库中什么也没有插入。这很奇怪,因为当我将函数调用替换为select 1
并向其中添加.fetchall()
时,它会被执行,并且在打印时会在控制台中看到结果。
假设我两次运行此代码,但没有任何反应,但是代码运行成功,没有错误。
如果我现在切换到数据库并运行select staging.test();
并选择my_table,则会得到:id: 3; name: yay insert
。
因此,这意味着当我运行Python文件时,序列实际上正在增加,但表中没有数据。
我在做什么错?我想念什么吗?我用谷歌搜索,但没有找到任何东西。
答案 0 :(得分:0)
此特定用例在"Understanding Autocommit"中被选中:
使用
Connection.execution_options()
,Connection
,Engine
上提供的生成Executable
方法并使用“ autocommit”标志,可以完全控制“自动提交”行为打开或关闭选定范围的自动提交。例如,表示提交的存储过程的text()
构造可能会使用它,以便SELECT语句将发出COMMIT:engine.execute(text("SELECT my_mutating_procedure()").execution_options(autocommit=True))
SQLAlchemy自动提交检测数据更改操作的方式是,它将语句与模式匹配,以查找诸如UPDATE,DELETE之类的内容。它无法检测存储的功能/过程是否执行了突变,因此提供了对自动提交的显式控制。
即使因为nextval()
and setval()
calls are never rolled back而失败,该序列也会递增。