提问人:yevt 提问时间:2/9/2023 最后编辑:yevt 更新时间:2/18/2023 访问量:594
为什么sqlalchemy postgres引擎连接会自动提交?
Why sqlalchemy postgres engine connection commits automatically?
问:
由于某种原因,引擎连接会自动提交,这是不希望的。我想明确提交。这是我的代码(它逐字重复官方教程):
from sqlalchemy import Table, Column, ForeignKey, Integer, String
from sqlalchemy.orm import relationship
from sqlalchemy.orm import registry
from sqlalchemy import create_engine
from sqlalchemy import ForeignKey
engine = create_engine('postgresql+psycopg2://user:password@localhost:5432/test_db', echo=True)
mapper_registry = registry()
Base = mapper_registry.generate_base()
user_table = Table(
"user_account",
mapper_registry.metadata,
Column("id", Integer, primary_key=True),
Column("name", String(30)),
Column("fullname", String),
)
mapper_registry.metadata.create_all(engine)
stmt = insert(user_table).values(name="spongebob", fullname="Spongebob Squarepants")
print(stmt)
with engine.connect() as conn:
result = conn.execute(stmt)
# conn.commit()
即使没有提交,我的日志也是:
INSERT INTO user_account (name, fullname) VALUES (:name, :fullname)
2023-02-09 16:12:05,033 INFO sqlalchemy.engine.Engine INSERT INTO user_account (name, fullname) VALUES (%(name)s, %(fullname)s) RETURNING user_account.id
2023-02-09 16:12:05,034 INFO sqlalchemy.engine.Engine [generated in 0.00123s] {'name': 'spongebob', 'fullname': 'Spongebob Squarepants'}
2023-02-09 16:12:05,037 INFO sqlalchemy.engine.Engine COMMIT
并且新对象出现在数据库中。
我试图设置,但没有成功conn.execution_options(isolation_level="SERIALIZABLE")
create_engine(...).execution_options(isolation_level="SERIALIZABLE")
但是,当我设置为 时,日志略有不同(因此我确信isolation_level选项被正确解释):isolation_level
"AUTOCOMMIT"
INSERT INTO user_account (name, fullname) VALUES (:name, :fullname)
2023-02-09 16:17:35,889 INFO sqlalchemy.engine.Engine INSERT INTO user_account (name, fullname) VALUES (%(name)s, %(fullname)s) RETURNING user_account.id
2023-02-09 16:17:35,890 INFO sqlalchemy.engine.Engine [generated in 0.00132s] {'name': 'spongebob', 'fullname': 'Spongebob Squarepants'}
2023-02-09 16:17:35,893 INFO sqlalchemy.engine.Engine COMMIT using DBAPI connection.commit(), DBAPI should ignore due to autocommit mode
sqlalchemy.__version__
'1.4.46'
这种行为的原因是什么?
我有什么不明白的?
我错过了什么?
谢谢
重要更新
正如@snakecharmerb所指出的,它按预期工作(这是与文档的唯一显着区别)。fututre=true
engine = create_engine('...url', echo=True, future=True**)
因此,此标志会更改自动提交行为。
INSERT INTO user_account (name, fullname) VALUES (:name, :fullname)
2023-02-09 17:42:08,499 INFO sqlalchemy.engine.Engine BEGIN (implicit)
2023-02-09 17:42:08,499 INFO sqlalchemy.engine.Engine INSERT INTO user_account (name, fullname) VALUES (%(name)s, %(fullname)s) RETURNING user_account.id
2023-02-09 17:42:08,500 INFO sqlalchemy.engine.Engine [generated in 0.00085s] {'name': 'spongebob', 'fullname': 'Spongebob Squarepants'}
<sqlalchemy.engine.cursor.CursorResult object at 0x7fef30f76ac0>
2023-02-09 17:42:10,511 INFO sqlalchemy.engine.Engine ROLLBACK
它主要回答了我的问题,但我仍然很好奇我是否可以在没有 的情况下有类似的行为,因为我还不能打开它(对于我从事的项目)future=True
答:
1赞
yevt
2/10/2023
#1
还行。现在很清楚了。 和是不同的东西。(它们应该是相关的,但这超出了当前问题的范围)autocommit
isolation_level
autocommit
如果 ,则默认关闭,否则默认打开。future=True
- 如果您无法设置但仍想关闭,您有 2 个选项(至少):
future=True
autocommit
2.1 传递给:autocommit=false
connection
with engine.connect().execution_options(autocommit=False) as conn
2.2 传递给:autocommit=false
engine
engine = create_engine('...dburl', echo=True).execution_options(autocommit=False)
评论
future=True
create_engine
future=True
with engine.connect().execution_options(autocommit=False) as conn