【问题标题】:Two ways of creating a flask-SQLAlchemy BaseQuery object - only one works, why?创建 flask-SQLAlchemy BaseQuery 对象的两种方法 - 只有一种有效,为什么?
【发布时间】:2015-05-01 10:20:34
【问题描述】:

这个问题是“Filter relationships and paginate in Flask-SQLAlchemy”的简化,这里的答案可能也会在那里产生一个解决方案。

假设我有一个简单的模型类设计:

from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy
app = Flask(__name__)
db = SQLAlchemy(app)

class Design(db.Model):
    __tablename__ = 'design'
    id = db.Column(db.Integer, primary_key=True)
    designname = db.Column(db.String(64))

我可以像这样得到一个 Flask-SQLAlchemy BaseQuery 对象:

>>> Design.query
<flask_sqlalchemy.BaseQuery object at 0x7f0b29c63990>

而且我可以如你所愿地取回数据:

>>> Design.query.all()
[<item1>, <item2>, <item3>]

我也可以通过这种方式获取 BaseQuery 对象(我认为这对于更复杂的查询是必要的,例如,带有连接的查询):

>>> db.Query(Design)
<flask_sqlalchemy.BaseQuery object at 0x7f0b29c6fdd0>

看起来它应该是相同的对象类型——事实上,生成的 SQL 是相同的:

>>> str(db.Query(Design)) ==  str(Design.query)
True

然而,当我在这里尝试 all() 方法时,它不起作用:

>>> db.Query(Design).all()
Traceback (most recent call last):
File "<debugger>", line 1, in <module>
db.Query(Design).all()
File "/usr/local/lib/python2.7/dist-packages/sqlalchemy/orm/query.py", line 2320, in all
return list(self)
File "/usr/local/lib/python2.7/dist-packages/sqlalchemy/orm/query.py", line 2437, in __iter__
self.session._autoflush()
AttributeError: 'NoneType' object has no attribute '_autoflush'

编辑:我认为问题在于第二种方法没有将会话附加到 BaseQuery 对象。第一种方法有一个:

>>> Design.query.session
<flask_sqlalchemy.SignallingSession object at 0x7f0b29fbd510>

但另一种方法没有:

>>> db.Query(Design).session is None
True

非常感谢任何见解。

【问题讨论】:

    标签: python flask sqlalchemy flask-sqlalchemy


    【解决方案1】:

    你应该可以使用

    db.session.query(Design).all()
    

    session.query 是在不使用 Flask-SQLAlchemy 的情况下使用 SQLAlchemy 时执行查询的方式。

    更新

    使用 Flask-SQLAlchemy 的 BaseQuery 执行连接:

    Design.query.join(YourOtherModel).all()
    

    【讨论】:

    • 是的,谢谢,但我已经知道如何通过常规 SQLAlchemy 会话来做到这一点。我特别尝试使用这种替代语法创建一个 flask_SQLAlchemy BaseQuery。我这样做的原因与我引用的其他 SE 问题相同 - 我想使用 BaseQuery 类中提供的分页。我应该在这个问题上更清楚地说明这一点。
    • 我想我只是不清楚你为什么不能使用Design.query
    • 如果您能告诉我如何将Design.query 与表连接一起使用,那就太好了,我会接受答案。我试图通过会话对象获取的原因是我需要做一个表连接——在纯 SQLAlchemy 中,它看起来像db.session.query(Parent, Child).join(Child).all()——所以我希望我可以用烧瓶扩展来做到这一点, db.Query(Parent, Child.join(Child).all() 之类的东西,但这不起作用。我的问题是对这个问题的简化......如果flask 不返回会话绑定对象,那么flask 的db.Query 是什么?
    • Design.query.join(YourOtherModel).all()
    • 是的,完美。感谢您对我公认的初学者问题的帮助。
    猜你喜欢
    • 2020-04-18
    • 2012-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-04
    • 1970-01-01
    • 2022-08-10
    • 2013-04-13
    相关资源
    最近更新 更多