更新 Pyramid 应用程序时 SQLAlchemy 的 ZopeTransactionEvents 错误是什么?
What is this ZopeTransactionEvents error with SQLAlchemy while updating a Pyramid application?
我正在将 Pyramid/SQLAlchemy 遗留代码更新为 Python 3.8,该应用程序在 Python 2.7 下运行良好,并且在本地 运行。所有必要的要求都已安装 pip,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()))
在主应用程序中,在获得最终输入并尝试将其添加到位于 DBSession.add(user)
:
的数据库后,此函数失败并显示 'ZopeTransactionEvents' object has no attribute 'after_commit'
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))
这里是堆栈跟踪的两个关键部分:
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:
[废话省略]
"[...]sqlalchemy/orm/deprecated_interfaces.py", line 367, in _adapt_listener
ls_meth = getattr(listener, meth)
AttributeError: 'ZopeTransactionEvents' object has no attribute 'after_commit'
这个特定问题使进程停止,尽管经过数天的研究(以及一些无用的黑客攻击),我仍未找到解决方案。这是一个遗留项目,我以前不熟悉 Pyramid 或 SQAlchemy,所以在我前进的过程中找到我的路。
固定
最后,这就是有效的方法,即 sessionmaker()
没有参数
from zope.sqlalchemy import register
# ...
DBSession = scoped_session(sessionmaker())
register(DBSession)
现在进入下一个错误。
这是由于 zope.sqlalchemy v1.2 中引入的重大更改。请参阅 zope.sqlalchemy pypi page
中的详细信息
To make things clearer we renamed the ZopeTransactionExtension class to ZopeTransactionEvents. Existing code using the ‘register’ version stays compatible.
从 1.1 升级
你的旧代码是这样的:
from zope.sqlalchemy import ZopeTransactionExtension
DBSession = scoped_session(sessionmaker(extension=ZopeTransactionExtension(), **options))
变为:
from zope.sqlalchemy import register
DBSession = scoped_session(sessionmaker(**options))
register(DBSession)
编辑
本质上它是对 1.2 版中引入的 zope.sqlalchemy
API 的一个小的破坏性更改,现在是 方式 。您现在不是通过关键字参数注册扩展,而是使用 register
可调用项显式注册会话。
以上内容直接引用自文档。它可能并不明显,但 **options
的使用是指可选的关键字参数。如果你没有使用任何关键字参数,那么这将被省略(即只调用 sessionmaker()
不带参数)。
我正在将 Pyramid/SQLAlchemy 遗留代码更新为 Python 3.8,该应用程序在 Python 2.7 下运行良好,并且在本地 运行。所有必要的要求都已安装 pip,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()))
在主应用程序中,在获得最终输入并尝试将其添加到位于 DBSession.add(user)
:
'ZopeTransactionEvents' object has no attribute 'after_commit'
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))
这里是堆栈跟踪的两个关键部分:
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:
[废话省略]
"[...]sqlalchemy/orm/deprecated_interfaces.py", line 367, in _adapt_listener
ls_meth = getattr(listener, meth)
AttributeError: 'ZopeTransactionEvents' object has no attribute 'after_commit'
这个特定问题使进程停止,尽管经过数天的研究(以及一些无用的黑客攻击),我仍未找到解决方案。这是一个遗留项目,我以前不熟悉 Pyramid 或 SQAlchemy,所以在我前进的过程中找到我的路。
固定
最后,这就是有效的方法,即 sessionmaker()
from zope.sqlalchemy import register
# ...
DBSession = scoped_session(sessionmaker())
register(DBSession)
现在进入下一个错误。
这是由于 zope.sqlalchemy v1.2 中引入的重大更改。请参阅 zope.sqlalchemy pypi page
中的详细信息To make things clearer we renamed the ZopeTransactionExtension class to ZopeTransactionEvents. Existing code using the ‘register’ version stays compatible.
从 1.1 升级
你的旧代码是这样的:
from zope.sqlalchemy import ZopeTransactionExtension
DBSession = scoped_session(sessionmaker(extension=ZopeTransactionExtension(), **options))
变为:
from zope.sqlalchemy import register
DBSession = scoped_session(sessionmaker(**options))
register(DBSession)
编辑
本质上它是对 1.2 版中引入的 zope.sqlalchemy
API 的一个小的破坏性更改,现在是 方式 。您现在不是通过关键字参数注册扩展,而是使用 register
可调用项显式注册会话。
以上内容直接引用自文档。它可能并不明显,但 **options
的使用是指可选的关键字参数。如果你没有使用任何关键字参数,那么这将被省略(即只调用 sessionmaker()
不带参数)。