SQLAlchemy中的Model.query和session.query(Model)有什么区别?

Cos*_*una 38 python sqlalchemy

我是SQLAlchemy的初学者,发现查询可以用2种方法完成:

方法1:

DBSession = scoped_session(sessionmaker())
class _Base(object):
    query = DBSession.query_property()

Base = declarative_base(cls=_Base)

class SomeModel(Base):
    key   = Column(Unicode, primary_key=True)
    value = Column(Unicode)

# When querying
result = SomeModel.query.filter(...)
Run Code Online (Sandbox Code Playgroud)

方法2

DBSession = scoped_session(sessionmaker())
Base = declarative_base()

class SomeModel(Base):
    key   = Column(Unicode, primary_key=True)
    value = Column(Unicode)

# When querying
session = DBSession()
result = session.query(SomeModel).filter(...)
Run Code Online (Sandbox Code Playgroud)

它们之间有什么区别吗?

gly*_*bet 10

在上面的代码中,没有区别.这是因为,在第一个例子的第3行:

  • query属性明确绑定到DBSession
  • 没有自定义Query对象传递给query_property

正如@ petr-viktorin在这里答案中指出的那样,在第一个示例中定义模型之前必须有一个会话,这可能会有问题,具体取决于应用程序的结构.

但是,如果您需要一个自动向所有查询添加其他查询参数的自定义查询,那么只有第一个示例才允许这样做.继承自定义查询类sqlalchemy.orm.query.Query可以作为参数传递给query_property.这个问题显示了该模式的一个例子.

即使模型对象上定义了自定义查询属性,查询时也不会使用该属性session.query,如第二个示例中的最后一行所示.如果您需要自定义查询类,这意味着第一个示例是唯一的选项.


Pet*_*rin 7

我看到以下缺点query_property

  • 您不能在与您配置的会话不同的会话上使用它(尽管您始终可以使用它session.query)。
  • 在定义架构之前,您需要一个可用的会话对象。

例如,当您想编写测试时,这些可能会困扰您。

此外,session.query更适合 SQLAlchemy 的工作方式;query_property看起来它只是为了方便而添加在顶部(或与其他系统相似?)。我建议你坚持session.query


Rob*_*ert 5

对不同 SQLAlchemy 问题的回答(此处)可能会有所帮助。那个答案开始于:

您可以使用Model.query,因为Model(或通常是它的基类,尤其是在使用声明性扩展的情况下)被分配了Session.query_property。在这种情况下Model.query相当于Session.query(Model)