engine.begin() 和 engine.connect() 有什么区别?

Jak*_*kob 6 python transactions sqlalchemy commit

我首先直接回答我的问题:如果第二个更可靠,为什么一个人宁愿使用engine.connect()而不是使用?engine.begin()那么,为什么它仍然出现在 SQLAlchemy 的教程页面以及 stackoverflow 中的各处?表现?

为什么engine.connect()工作如此不一致?是自动提交的问题吗?

我的背景故事是,我刚刚解决了一个问题。普通的 SQL 查询,例如SELECT,CREATE TABLE和 ,DELETE在使用 时可以完美地工作engine.connect()。不过,使用起来MERGE会非常不一致。有时提交,有时阻止其他查询,有时什么也不做。这里推荐用于engine.begin()查询MERGE

所以我替换了以下代码:

with engine.connect() as connection:
    connection.execute('MERGE Table1 USING Table2 ON .....')
Run Code Online (Sandbox Code Playgroud)

经过

with engine.begin() as connection:
    connection.execute('MERGE Table1 USING Table2 ON .....')
Run Code Online (Sandbox Code Playgroud)

现在一切都很完美。SELECT包括、CREATE TABLE和的查询DELETE。在SQLAlchemy 文档中,它说第二个选项使用带有事务提交的事务,但其范围也with engine.connect()执行自动提交。抱歉,我是 SQL 的新手。

Gor*_*son 7

with engine.connect() 的范围也执行自动提交

不,事实并非如此。with engine.connect()这是和 之间最显着的区别with engine.begin()

with engine.connect() as conn:
    # do stuff
# on exit, the transaction is automatically rolled back

with engine.begin() as conn:
    # do stuff
# on exit, the transaction is automatically committed if no errors occurred
Run Code Online (Sandbox Code Playgroud)

正如教程中提到的engine.connect()与“[显式]随心提交”风格的代码一起使用,而engine.begin()代表“开始一次”风格。

这两种情况都使用事务。但是,engine.begin()立即开始事务,而engine.connect()等待语句执行后再开始事务。这允许我们改变最终将启动的交易的特征。此功能的常见用途engine.connect()是使用非默认事务隔离:

# default isolation level
with engine.connect() as conn:
    print(conn.get_isolation_level())  # REPEATABLE READ

# using another isolation level
with engine.connect().execution_options(
    isolation_level="SERIALIZABLE"
) as conn:
    print(conn.get_isolation_level())  # SERIALIZABLE
Run Code Online (Sandbox Code Playgroud)