SQLAlchemy db.session.query()vs model.query

DTo*_*own 10 sqlalchemy

对于简单的返回,所有结果查询应该优先于另一种方法吗?我可以在网上找到两种用途,但实际上找不到任何描述差异的东西.

db.session.query([my model name]).all()

[my model name].query.all()
Run Code Online (Sandbox Code Playgroud)

我觉得[我的模型名称] .query.all()更具描述性.

Ang*_*los 5

很难给出明确的答案,因为在回答这个问题时存在高度的偏好主观性。

从一个角度来看,需要db.session,因为第二种方法要求将db.session作为一个附加步骤并入您的模型-默认情况下,它不属于Base类。例如:

Base = declarative_base()
DBSession = scoped_session(sessionmaker())
class User(Base):
   __tablename__ = 'users'

   id = Column(Integer, primary_key=True)
   name = Column(String)
   fullname = Column(String)
   password = Column(String)
session = Session()
print(User.query)
Run Code Online (Sandbox Code Playgroud)

该代码失败,并出现以下错误:

AttributeError:类型对象“用户”没有属性“查询”

您需要执行以下操作:

class User(Base):
   __tablename__ = 'users'

   id = Column(Integer, primary_key=True)
   name = Column(String)
   fullname = Column(String)
   password = Column(String)
   query = DBSession.query_property()
Run Code Online (Sandbox Code Playgroud)

但是,也可能有人争辩说,仅仅因为默认情况下未启用它,才不会使它无效为启动查询的合理方式。此外,在flask-sqlalchemy软件包中(这简化了sqlalchemy与flask Web框架的集成),已经作为Model类(doc)的一部分为您完成了此操作。可以在sqlalchemy教程(doc)中看到将查询属性添加到模型中:

class User(object):
   query = db_session.query_property()
   ....
Run Code Online (Sandbox Code Playgroud)

因此,人们可以争论两种方法。

从单个表中进行选择时,我个人比较喜欢第二种方法。例如:

serv = Service.query.join(Supplier, SupplierUsr).filter(SupplierUsr.username == usr).all()
Run Code Online (Sandbox Code Playgroud)

这是因为它具有较小的行长并且仍然易于阅读。

如果要从多个表中进行选择或指定列,那么我将使用模型查询方法来从多个模型中提取信息。

deliverables = db.session.query(Deliverable.column1, BatchInstance.column2).\
    join(BatchInstance, Service, Supplier, SupplierUser). \
    filter(SupplierUser.username == str(current_user)).\
    order_by(Deliverable.created_time.desc()).all()
Run Code Online (Sandbox Code Playgroud)

就是说,可以始终使用session.query方法来产生一个计数器参数,因为它使代码更加一致,并且当从左向右阅读时,读者会立即知道他们将要读取的sqlalchemy指令将是查询,从精神上吸收涉及的表和列。

归根结底,问题的答案是主观的,没有正确的答案,任何一种代码可读性的好处都是很小的。我唯一能看到的强项就是,如果要从许多表中进行选择,则不要使用模型查询,而应使用session.query方法。