创建 flask-SQLAlchemy BaseQuery 对象的两种方法 - 只有一种有效,为什么?
Two ways of creating a flask-SQLAlchemy BaseQuery object - only one works, why?
这个问题是“Filter relationships and paginate in Flask-SQLAlchemy”的简化,这里的答案可能也会在那里产生解决方案。
假设我有一个简单的模型class设计:
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
非常感谢任何见解。
您应该可以使用
db.session.query(Design).all()
session.query
是在不使用 Flask-SQLAlchemy 的情况下使用 SQLAlchemy 时执行查询的方式。
更新
使用 Flask-SQLAlchemy 的 BaseQuery
执行连接:
Design.query.join(YourOtherModel).all()
这个问题是“Filter relationships and paginate in Flask-SQLAlchemy”的简化,这里的答案可能也会在那里产生解决方案。
假设我有一个简单的模型class设计:
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
非常感谢任何见解。
您应该可以使用
db.session.query(Design).all()
session.query
是在不使用 Flask-SQLAlchemy 的情况下使用 SQLAlchemy 时执行查询的方式。
更新
使用 Flask-SQLAlchemy 的 BaseQuery
执行连接:
Design.query.join(YourOtherModel).all()