当前位置: 首页 > 面试题库 >

SQLAlchemy-可以向查询对象添加自定义方法吗?

祝俊雄
2023-03-14
问题内容

有没有一种方法可以为查询对象创建自定义方法,以便您可以执行以下操作?

User.query.all_active()

all_active()本质上在哪里.filter(User.is_active == True)

并能够过滤掉它吗?

User.query.all_active().filter(User.age == 30)

问题答案:

您可以对基Query类进行子类化以添加自己的方法:

from sqlalchemy.orm import Query

class MyQuery(Query):

  def all_active(self):
    return self.filter(User.is_active == True)

然后,您可以在创建会话时告诉SQLAlchemy使用此新查询类(此处的文档)。从您的代码看来,您可能正在使用Flask-
SQLAlchemy,因此您可以按照以下步骤进行操作:

db = SQLAlchemy(session_options={'query_cls': MyQuery})

否则,您将参数直接传递给sessionmaker

sessionmaker(bind=engine, query_cls=MyQuery)

到目前为止,这个新的查询对象并不那么有趣,因为我们User在方法中对类进行了硬编码,因此它不能用于其他任何事情。更好的实现方式是使用查询的基础类来确定要应用的过滤器。这有点棘手,但也可以完成:

class MyOtherQuery(Query):

  def _get_models(self):
    """Returns the query's underlying model classes."""
    if hasattr(query, 'attr'):
      # we are dealing with a subquery
      return [query.attr.target_mapper]
    else:
      return [
        d['expr'].class_
        for d in query.column_descriptions
        if isinstance(d['expr'], Mapper)
      ]

  def all_active(self):
    model_class = self._get_models()[0]
    return self.filter(model_class.is_active == True)

最后,动态关系不会使用此新查询类(如果有的话)。为了让那些人也可以使用它,可以在创建关系时将其作为参数传递:

users = relationship(..., query_class=MyOtherQuery)


 类似资料:
  • 问题内容: 在Ruby中,您可以使用自定义方法覆盖任何内置对象类,如下所示: 我如何在python中做到这一点?有正常的方法还是黑客? 问题答案: 您不能这样做,因为内建类型是用C编码的。您可以对类型进行子类化: 测试: 您还可以使用来覆盖str-type ,但这并不意味着您可以使用文字,因为它链接到内建的。

  • 问题内容: 在Django中,如果我有模型类,例如 然后,如果我想向模型添加方法以存储例如相当复杂的过滤器,则可以添加自定义模型管理器,例如 然后我可以做: 有什么方法可以添加可链接到模型的查询集末尾的自定义方法? 即以一种我可以做到的方式添加自定义方法: 问题答案: 您需要向最终添加的方法添加方法。因此,您需要创建和使用一个子类,该子类具有在需要此功能的位置定义的方法。 我找到了本教程,该教程说

  • 问题内容: 我们有一个测试套件,主要使用带有Hamcrest匹配器的JUnit断言。我们的一个团队开始对AssertJ进行实验,并以其语法,灵活性和声明性给人留下了深刻的印象。JUnit提供的一项功能是我无法在AssertJ中找到与之等效的功能:添加自定义断言失败消息。 我们经常在比较不是为了人类可读性而制成的对象,这些对象将具有随机查找的Id或UUID,并且无法通过包含的数据来判断它们应该是什么

  • 我们经常比较那些不是为了人类可读性而制作的对象,这些对象将具有随机的ID或UUID,并且不可能根据它们包含的数据来判断它们应该是什么。对于我们的代码库来说,这是一个不可避免的情况,可悲的是,它实现的目的之一是在其他服务之间映射数据,而不需要理解它是什么。 在JUnit中,方法提供的版本在参数之前带有参数。这使得添加一个简短的调试字符串变得微不足道,从而揭示了一些问题,比如比较对人类应该意味着什么。

  • 问题内容: 假设我有一个对象 如何通过添加方法扩展该对象,并确保将来的实例具有此方法? 问题答案: 您需要将其添加到Foo的原型中:

  • 我必须将自定义方法方法添加到我的日志系统中。假设我有几行代码,例如: 日志记录由slf4j处理。如何通过添加新(!)扩展我的记录器方法,如public void error(SomeTypeObject obj){/implementation/} 目标是不更改现有代码。如何强制LoggerFactory返回使用上述方法扩展的自己的记录器实现? 我跟踪了这个问题的答案:stackoverflow.