如何解决更新金字塔应用程序时,SQLAlchemy的ZopeTransactionEvents错误是什么? 编辑
我正在从一个在Python 2.7下可以正常工作的应用程序中将Pyramid / sqlAlchemy旧代码更新为Python 3.8,并在本地运行它。所有必要的要求都已安装pip,setup.py可以正常运行。
使用我的本地.ini文件运行initialise
时,一切顺利,数据库表(MariaDB)均已写入。
在models.py
中from sqlalchemy.orm import (
scoped_session,sessionmaker,relationship,backref,synonym,)
from zope.sqlalchemy import ZopeTransactionEvents
#[...]
DBSession = scoped_session(sessionmaker(extension=ZopeTransactionEvents()))
在主应用程序中,获得最终输入并尝试将其添加到'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))
这是堆栈跟踪的两个关键部分:
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
中查看详细信息为使事情更清楚,我们将ZopeTransactionExtension类重命名为ZopeTransactionEvents。使用“注册”版本的现有代码保持兼容。
要从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()
,不带参数)。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。