Python sqlalchemy 烧瓶:AttributeError:'Session' 对象在 session.commit() 上没有属性 '_model_changes'

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20201809/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 19:51:59  来源:igfitidea点击:

sqlalchemy flask: AttributeError: 'Session' object has no attribute '_model_changes' on session.commit()

pythonsqlalchemyflaskflask-sqlalchemy

提问by bhoward

I've seen a lot of problems with SessionMaker, but this one is slightly different. Not sure why, but sqlalchemy won't let my session object commit.

我已经看到 SessionMaker 有很多问题,但这个问题略有不同。不知道为什么,但 sqlalchemy 不会让我的会话对象提交。

In my app, I have some code that does:

在我的应用程序中,我有一些代码可以:

views.py

视图.py

rec = session.query(Records).filter(Records.id==r).first()
n = rec.checkoutRecord(current_user.id)
session.add(n)
session.commit()

models.py:

模型.py:

class Records(UserMixin, CRUDMixin, Base):
    __table__ = Table('main_records', Base.metadata, autoload=True)


    def checkoutRecord(self,uid):
        self.editing_uid = uid 
        self.date_out = datetime.now()
        return self

    def checkinRecord(self,uid):
        self.editing_uid = uid 
        self.date_in = datetime.now()
        return self

The program craps out on the commit(), giving the above exception. Interestingly, some test code which does not import flask, but does import sqlalchemy works fine and lets me commit without error.

程序在 commit() 上失败了,给出了上述异常。有趣的是,一些不导入烧瓶但导入 sqlalchemy 的测试代码工作正常,让我无误地提交。

The full stack-trace:

完整的堆栈跟踪:

Traceback (most recent call last):
  File "/Users/bhoward/Envs/py27/lib/python2.7/site-packages/flask/app.py", line 1475, in full_dispatch_request
    rv = self.dispatch_request()
  File "/Users/bhoward/Envs/py27/lib/python2.7/site-packages/flask/app.py", line 1461, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/Users/bhoward/Envs/py27/lib/python2.7/site-packages/flask_login.py", line 663, in decorated_view
    return func(*args, **kwargs)
  File "/Users/bhoward/projects/PeerCoUI/mk2/peercoui/app/records/views.py", line 65, in select_view
    session.commit()
  File "/Users/bhoward/Envs/py27/lib/python2.7/site-packages/sqlalchemy/orm/scoping.py", line 149, in do
    return getattr(self.registry(), name)(*args, **kwargs)
  File "/Users/bhoward/Envs/py27/lib/python2.7/site-packages/sqlalchemy/orm/session.py", line 721, in commit
    self.transaction.commit()
  File "/Users/bhoward/Envs/py27/lib/python2.7/site-packages/sqlalchemy/orm/session.py", line 354, in commit
    self._prepare_impl()
  File "/Users/bhoward/Envs/py27/lib/python2.7/site-packages/sqlalchemy/orm/session.py", line 323, in _prepare_impl
    self.session.dispatch.before_commit(self.session)
  File "/Users/bhoward/Envs/py27/lib/python2.7/site-packages/sqlalchemy/event.py", line 372, in __call__
    fn(*args, **kw)
  File "/Users/bhoward/Envs/py27/lib/python2.7/site-packages/flask_sqlalchemy/__init__.py", line 162, in session_signal_before_commit
    d = session._model_changes
AttributeError: 'Session' object has no attribute '_model_changes'

Full code for the project is in github: https://github.com/bhoward00/peercoui

该项目的完整代码在github:https: //github.com/bhoward00/peercoui

Any advice appreciated

任何建议表示赞赏

采纳答案by jbub

Yes this is exactly problem when using flask-sqlalchemymodels mixed with pure sqlalchemysession. Thing is that flask-sqlalchemysubclasses the base Sessionfrom sqlalchemyand adds some internals one of which is the _model_changesdict. This dict is used for model modification tracking.

是的,这正是使用flask-sqlalchemy与纯sqlalchemy会话混合的模型时的问题。事情是从flask-sqlalchemy基类继承并添加一些内部结构,其中之一是dict。该字典用于模型修改跟踪。Sessionsqlalchemy_model_changes

So if you want to use flask-sqlalchemybased models with regular sqlalchemysession, one way would be to just add the dict to the session (this is just example code):

因此,如果您想在flask-sqlalchemy常规sqlalchemy会话中使用基于模型的模型,一种方法是将 dict 添加到会话中(这只是示例代码):

def create_session(config):
    engine = create_engine(config['DATABASE_URI'])
    Session = sessionmaker(bind=engine)
    session = Session()
    session._model_changes = {}
    return session 

I had the same exact problem as you, so hopefully this should help you.

我和你有同样的问题,所以希望这对你有帮助。

UPDATE:

更新:

There is new version available, which should be fixing this behaviour, quoting the 2.0 docs:

有新版本可用,它应该修复此行为,引用 2.0 文档:

Changed how the builtin signals are subscribed to skip non Flask-SQLAlchemy sessions. This will also fix the attribute error about model changes not existing.

更改了订阅内置信号的方式以跳过非 Flask-SQLAlchemy 会话。这也将修复有关模型更改不存在的属性错误。

Docs: http://flask-sqlalchemy.pocoo.org/2.0/changelog/#version-2-0

文档:http: //flask-sqlalchemy.pocoo.org/2.0/changelog/#version-2-0

回答by olipo186

I had the same problem as well, and solved it by modifying the _SessionSignalEvents class within init.py in flask-sqlalchemy. However, I just noticed that such a fix had already been in place since 8 months on the official repository.

我也遇到了同样的问题,并通过修改flask- sqlalchemy 中init.py 中的 _SessionSignalEvents 类解决了这个问题。但是,我刚刚注意到官方存储库中已经有 8 个月的时间进行了这样的修复。

If you encounter a similar problem, I would recomment you to pull the latest version of the project off github (https://github.com/mitsuhiko/flask-sqlalchemy/) since the one currently available through pip install is outdated.

如果您遇到类似的问题,我建议您从 github ( https://github.com/mitsuhiko/flask-sqlalchemy/)上拉取该项目的最新版本,因为当前通过 pip install 可用的版本已过时。