【问题标题】:Pyramid dbsession always does rollbackPyramid dbsession 总是回滚
【发布时间】:2018-09-25 06:38:26
【问题描述】:

我正在尝试使用金字塔的事务管理器来提交更改。不幸的是,无论我做什么,它们都会被回滚。

我尝试了简单的:

def handle(conn):
    conn.execute('''ALTER TABLE ....''')

with bootstrap(sys.argv[1]) as env:
    with env['request'].tm:
        handle(env['request'].dbsession)

以及下拉到连接并创建显式事务:

def handle(conn):
    with conn.begin() as tran:
        conn.execute('''ALTER TABLE ....''')
        tran.commit()

with bootstrap(sys.argv[1]) as env:
    with env['request'].tm:
        handle(env['request'].dbsession.connection())

还有其他几种方式,但每次我都会得到ROLLBACK 而不是COMMIT

在第一种情况结束时进行简单的提交会导致:

Error: Transaction must be committed using the transaction manager

我对 sqlalchemy 在这种情况下实际上在做什么感到很迷茫——为什么我会通过回滚获得“成功”?我应该怎么做才能承诺?如果在 handle 中存在嵌套的显式事务,它会是什么样子?

【问题讨论】:

标签: python sqlalchemy pyramid


【解决方案1】:

正如 ilja 在 cmets 中所说,正确的答案是,当您直接在连接上操作而不是通过 ORM 操作在 ORM 会话上操作时,zope.sqlalchemy 不可能知道您是否进行了更改。默认情况下,zope.sqlalchemy 要求您使用 ORM 或手动标记会话已更改。

from zope.sqlalchemy import mark_changed

mark_changed(env['request'].dbsession)

或者,如果这对您来说是一种常见模式,那么您可以将 zope.sqlalchemy 配置为始终假设会话已更改,因此默认情况下发出提交而不是回滚。

zope.sqlalchemy.register(..., initial_state='changed')

您的代码中已经有这样的调用,您只需添加initial_state 属性。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-03-04
    • 1970-01-01
    • 1970-01-01
    • 2016-04-19
    • 2013-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多