更新 Pyramid 应用程序时 SQLAlchemy 出现的 ZopeTransactionEvents 错误是什么?

Dav*_*itt 1 python pylons sqlalchemy python-3.x pyramid

我正在将 Pyramid/SQLAlchemy 遗留代码从在 Python 2.7 下正常工作的应用程序更新到 Python 3.8,并在本地运行它。所有必要的要求都已安装,并且 setup.py 运行没有错误。

initialise使用本地 .ini 文件运行时,一切顺利,数据库表 (MariaDB) 均已写入。

在 models.py 中

from sqlalchemy.orm import (
    scoped_session,
    sessionmaker,
    relationship,
    backref,
    synonym,
    )
from zope.sqlalchemy import ZopeTransactionEvents
#[...]
DBSession = scoped_session(sessionmaker(extension=ZopeTransactionEvents()))
Run Code Online (Sandbox Code Playgroud)

'ZopeTransactionEvents' object has no attribute 'after_commit'在主应用程序中,在获得最终输入并尝试将其添加到数据库后,此函数失败DBSession.add(user)

def do_create_admin_user(self):
    from ..models import User
    from getpass import getpass
    print("Create an administrative user")
    fullname = input("full name: ")
    username = input("username: ")
    if not username:
        self.log.info("missing username - aborted")
        return
    if len(username) > 50:
        self.log.info("username too long - aborted")
        return
    password = getpass("password for {}: ".format(username))

    with transaction.manager:
        user = User(
            username=username,
            fullname=fullname,
            administrator=True,
            password=password
        )
        DBSession.add(user)
    self.log.info("{} created".format(username))

Run Code Online (Sandbox Code Playgroud)

以下是堆栈跟踪的两个关键部分:

Traceback (most recent call last):
"[...]sqlalchemy/util/_collections.py", line 1055, in __call__
    return self.registry.value
AttributeError: '_thread._local' object has no attribute 'value'

During handling of the above exception, another exception occurred:
Run Code Online (Sandbox Code Playgroud)

[粗略省略]

"[...]sqlalchemy/orm/deprecated_interfaces.py", line 367, in _adapt_listener
    ls_meth = getattr(listener, meth)
AttributeError: 'ZopeTransactionEvents' object has no attribute 'after_commit'
Run Code Online (Sandbox Code Playgroud)

这个具体问题停止了这个过程,尽管经过几天的研究(以及一些无效的黑客攻击),我仍然没有接近解决方案。这是一个遗留项目,我以前不熟悉 Pyramid 或 SQAlchemy,因此在进行过程中找到自己的方法。


固定的

最后,这就是有效的,即没有争议sessionmaker()

from zope.sqlalchemy import register
# ...
DBSession = scoped_session(sessionmaker())
register(DBSession)
Run Code Online (Sandbox Code Playgroud)

现在讨论下一个错误。

Gra*_*art 5

这是由于 zope.sqlalchemy v1.2 中引入的重大更改所致。请参阅zope.sqlalchemy pypi 页面中的详细信息

\n
\n

为了使事情更清楚,我们将 ZopeTransactionExtension 类重命名为 ZopeTransactionEvents。使用 \xe2\x80\x98register\xe2\x80\x99 版本的现有代码保持兼容。

\n
\n

从1.1升级

\n

你的旧代码是这样的:

\n
from zope.sqlalchemy import ZopeTransactionExtension\n\nDBSession = scoped_session(sessionmaker(extension=ZopeTransactionExtension(), **options))\n
Run Code Online (Sandbox Code Playgroud)\n

变成:

\n
from zope.sqlalchemy import register\n\nDBSession = scoped_session(sessionmaker(**options))\nregister(DBSession)\n
Run Code Online (Sandbox Code Playgroud)\n

编辑

\n

zope.sqlalchemy本质上,这是对 1.2 版本中引入的 API 的一个微小的重大更改,现在就是这样。现在,您不再通过关键字参数注册扩展,而是使用可调用函数显式注册会话register

\n

以上是直接引用自文档。它可能并不明显,但使用引用**options可选关键字参数。如果您没有使用任何关键字参数,那么这将被省略(即只调用sessionmaker()不带参数)。

\n