为什么sqlalchemy postgres引擎连接会自动提交?

Why sqlalchemy postgres engine connection commits automatically?

提问人:yevt 提问时间:2/9/2023 最后编辑:yevt 更新时间:2/18/2023 访问量:594

问:

由于某种原因,引擎连接会自动提交,这是不希望的。我想明确提交。这是我的代码(它逐字重复官方教程):

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

python postgresql sqlalchemy 自动提交

评论

1赞 snakecharmerb 2/9/2023
您安装了哪个版本的 SQLAlchemy?
0赞 yevt 2/9/2023
@snakecharmerb 1.4.46
1赞 snakecharmerb 2/9/2023
如果您添加到调用中,它是否按预期工作?future=Truecreate_engine
0赞 yevt 2/9/2023
@snakecharmerb是的,现在它的行为符合预期。Howeher,我可以在没有的情况下得到类似的结果吗?因为我还不能为我从事的项目打开这个标志future=True
1赞 python_user 2/10/2023
@yevt有效?with engine.connect().execution_options(autocommit=False) as conn

答:

1赞 yevt 2/10/2023 #1

还行。现在很清楚了。 和是不同的东西。(它们应该是相关的,但这超出了当前问题的范围)autocommitisolation_level

  1. autocommit如果 ,则默认关闭,否则默认打开future=True
  2. 如果您无法设置但仍想关闭,您有 2 个选项(至少):future=Trueautocommit

2.1 传递给:autocommit=falseconnection

with engine.connect().execution_options(autocommit=False) as conn

2.2 传递给:autocommit=falseengine

engine = create_engine('...dburl', echo=True).execution_options(autocommit=False)