【问题标题】:sqlalchemy flask: AttributeError: 'Session' object has no attribute '_model_changes' on session.commit()sqlalchemy烧瓶:AttributeError:'Session'对象在session.commit()上没有属性'_model_changes'
【发布时间】:2013-12-10 16:40:34
【问题描述】:

我发现 SessionMaker 存在很多问题,但这个问题略有不同。不知道为什么,但是 sqlalchemy 不会让我的会话对象提交。

在我的应用中,我有一些代码:

views.py

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

models.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

程序在 commit() 上报废,出现上述异常。有趣的是,一些不导入flask但导入sqlalchemy的测试代码工作正常,让我可以毫无错误地提交。

完整的堆栈跟踪:

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'

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

任何建议表示赞赏

【问题讨论】:

  • 所以这个项目同时使用了flask-sqlalchemy和sqlalchemy。作为临时解决方法,我删除了 flask-sqlalchemy 的所有痕迹,一切似乎都很好。

标签: python sqlalchemy flask flask-sqlalchemy


【解决方案1】:

是的,当使用flask-sqlalchemy 模型与纯sqlalchemy 会话混合时,这正是问题。事情是flask-sqlalchemysqlalchemy 继承了基础Session 并添加了一些内部结构,其中之一是_model_changes dict。此 dict 用于模型修改跟踪。

因此,如果您想将基于 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 

我遇到了和你一样的问题,所以希望这对你有帮助。

更新:

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

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

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

【讨论】:

  • 我遇到了同样的问题,通过升级 SQLAlchemy 和 Flask-SQLAlchemy 解决了。我有旧版本的 SQLAlchmy (0.9.6) 和 Flask-SQLAlchemy (1.0)。我将 SQLAlchemy 升级到 0.9.8,将 Flask-SQLAlchemy 升级到 2.0。这为我解决了这个问题。我的环境是 Ubuntu 14.04.1 LTS 和 Python 2.7.6。
  • 今天我在 Windows 7 上遇到了同样的问题,同样的修复方法也奏效了:升级 Flask-SQLAlchemy。我不需要单独升级 SQLAlchemy;那是自动发生的。我所做的只是 pip install --upgrade Flask-SQLAlchemy。
  • 看起来在 flask-sqlalchmey 中添加修复与上面的代码相同(本质上):github.com/pallets/flask-sqlalchemy/pull/89
【解决方案2】:

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

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

【讨论】:

    猜你喜欢
    • 2021-10-15
    • 2022-11-13
    • 2014-09-02
    • 2019-08-14
    • 1970-01-01
    • 1970-01-01
    • 2020-07-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多