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

时间:2012-09-10 11:32:04

标签: 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(...)

方法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(...)

它们之间有什么区别吗?

3 个答案:

答案 0 :(得分:9)

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

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

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

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

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

答案 1 :(得分:2)

我认为这些缺点是query_property

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

例如,当您想要编写测试时,这些可能会让您感到痛苦。

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

答案 2 :(得分:2)

对不同的SQLAlchemy问题的回答(here)可能有所帮助。答案始于:

  

您可以使用Model.query,因为Model(或通常是其基类,特别是在使用声明性扩展的情况下)被指定为Sesssion.query_property。在这种情况下,Model.query相当于Session.query(Model)