很难给出明确的答案,因为回答这个问题存在高度的偏好主观性。
从一个角度来看,db.session 是需要的,因为第二种方法要求将其作为附加步骤合并到模型中 - 默认情况下它不作为基类的一部分存在。例如:
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)
该代码失败并出现以下错误:
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()
然而,也有人认为,仅仅因为默认情况下未启用它,并不意味着它作为启动查询的合理方式无效。此外,在 Flask-sqlalchemy 包(简化了 sqlalchemy 与 Flask Web 框架的集成)中,这已经作为 Model 类的一部分为您完成(doc) http://flask-sqlalchemy.pocoo.org/2.1/api/#flask.ext.sqlalchemy.Model。将查询属性添加到模型中也可以在 sqlalchemy 教程中看到(doc) http://flask.pocoo.org/docs/0.12/patterns/sqlalchemy/:
class User(object):
query = db_session.query_property()
....
因此,人们可以争论任何一种方法。
当我从单个表中进行选择时,我个人更喜欢第二种方法。例如:
serv = Service.query.join(Supplier, SupplierUsr).filter(SupplierUsr.username == usr).all()
这是因为它的行长度较短并且仍然易于阅读。
如果我从多个表中进行选择或指定列,那么我将使用模型查询方法,因为它从多个模型中提取信息。
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()
也就是说,可以在始终使用 session.query 方法时进行反论证,因为它使代码更加一致,并且当从左到右阅读时,读者立即知道他们要读取的 sqlalchemy 指令将在之前被查询精神上吸收所涉及的表和列。
归根结底,你的问题的答案是主观的,没有正确的答案,而且任何一种方式对代码可读性的好处都是很小的。我看到的唯一一个强大的好处是,如果您从许多表中进行选择,则不要使用模型查询,而是使用 session.query 方法。