63

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

方法一:

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

方法二

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

它们之间有什么区别吗?

4

3 回答 3

16

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

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

正如@petr-viktorin 在此处的答案中指出的那样,在第一个示例中定义模型之前,必须有一个可用的会话,这可能会根据应用程序的结构而存在问题。

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

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

于 2013-01-28T00:25:57.017 回答
5

一个不同的 SQLAlchemy 问题的答案(这里)可能会有所帮助。这个答案开始于:

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

于 2015-09-09T09:47:17.087 回答
3

我看到这些缺点query_property

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

例如,当您想编写测试时,这些可能会咬您一口。

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

于 2013-01-27T22:59:16.060 回答