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



我看到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

感谢的任何建议

是的,当使用混合了纯sqlalchemy会话的flask-sqlalchemy模型时,这正是问题所在。问题是flask-sqlalchemysqlalchemy的基础Session进行了子类化,并添加了一些内部元素,其中之一就是_model_changes dict。该dict用于模型修改跟踪。

因此,如果您想在常规sqlalchemy会话中使用基于flask-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

我也遇到了同样的问题,并通过在flask-sqlalchemy中修改__init__.py中的_SessionSignalEvents类来解决它。然而,我刚刚注意到,这样的修复程序在官方存储库上已经存在了8个月。

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

SQLAlchemy==1.4.x版本不适合我。

尽管更改为SQLAlchemy=1.3.18,但还是成功了

如何创建这样一个文件来指定已安装的版本?

  1. pip3冻结>requirements.txt
  2. pip3安装烧瓶
  3. pip3安装烧瓶sqlalchemy

编辑requirements.txt和SQLAlchemy条目,例如SQLAlchemy=1.3.18。

然后,重新运行您的虚拟环境-->烧瓶运行

如果您没有设置虚拟环境?

  • 蟒蛇3-m venv.venv
  • source.venv/bin/activate
  • 烧瓶运行

希望能有所帮助!

我解决了将session.exec交换到session.execute的问题。我没有对此进行深入分析。我认为这是由于SessionMaker返回了对象,而不是原始的Session

最新更新