更新 Pyramid 应用程序时 SQLAlchemy 的 ZopeTransactionEvents 错误是什么? [英] What is this ZopeTransactionEvents error with SQLAlchemy while updating a Pyramid application?

查看:96
本文介绍了更新 Pyramid 应用程序时 SQLAlchemy 的 ZopeTransactionEvents 错误是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm updating Pyramid/SQLAlchemy legacy code to Python 3.8 from an app working fine under Python 2.7, and running it locally. All the necessary requirements are pip installed and setup.py runs without error.

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

On running initialise with my local .ini file, All goes well, the database tables (MariaDB) are all written.

在models.py中

in models.py

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

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

in the main app it fails with 'ZopeTransactionEvents' object has no attribute 'after_commit' at this function, after getting the final input and attempting to add it to the DB at 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))

这里是堆栈跟踪的两个关键部分:

Here are the two key parts of the stack trace:

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,所以在我前进的过程中找到自己的方式.

This specific issue halted the process, and despite days of research (and some unproductive hacking) I'm no closer to a solution. This is a legacy project and I'm not previously familiar with Pyramid or SQAlchemy, so finding my way as I go along.

最后,这是有效的,即 sessionmaker()

In the end, this is what worked i.e. no arguments to sessionmaker()

from zope.sqlalchemy import register
# ...
DBSession = scoped_session(sessionmaker())
register(DBSession)

现在进入下一个错误.

推荐答案

这是由于 zope.sqlalchemy v1.2 中引入的重大更改.在 zope.sqlalchemy pypi 页面

This is due to a breaking change introduced in zope.sqlalchemy v1.2. See details in the zope.sqlalchemy pypi page

为了使事情更清楚,我们将 ZopeTransactionExtension 类重命名为 ZopeTransactionEvents.使用注册"版本的现有代码保持兼容.

To make things clearer we renamed the ZopeTransactionExtension class to ZopeTransactionEvents. Existing code using the ‘register’ version stays compatible.

从 1.1 升级

像这样的旧代码:

To upgrade from 1.1

Your old code like this:

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 显式注册会话.

edit

Essentially its a minor breaking change to the zope.sqlalchemy API that was introduced in version 1.2, this is now the way. Rather than registering the extension via keyword argument, you now register the session explicitly with the register callable.

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

The above is a direct quote from the documentation. It may not be obvious but the use of **options refers to optional keyword arguments. If you are not using any keyword arguments then this would be omitted (i.e. just call sessionmaker() with no arguments).

这篇关于更新 Pyramid 应用程序时 SQLAlchemy 的 ZopeTransactionEvents 错误是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆