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

在SQLAlchemy中动态构造过滤器

史阳晖
2023-03-14
问题内容

我正在寻找一种使用SQLAlchemy动态构造过滤器的方法。也就是说,给定该列,运算符名称和比较值,即可构造相应的过滤器。

我将尝试使用一个示例进行说明(这将用于构建API)。假设我们有以下模型:

class Cat(Model):

  id = Column(Integer, primary_key=True)
  name = Column(String)
  age = Column(Integer)

我想将查询映射到过滤器。例如,

  • /cats?filter=age;eq;3 应该产生 Cat.query.filter(Cat.age == 3)

  • /cats?filter=age;in;5,6,7&filter=id;ge;10 应该产生 Cat.query.filter(Cat.age.in_([5, 6, 7])).filter(Cat.id >= 10)

我环顾四周,看看它是如何完成的,但是找不到一种不涉及手动将每个运算符名称映射到比较器或类似名称的方法。例如,Flask-
Restless
保留所有支持的操作的字典,并存储相应的lambda函数(此处的代码)。

我在SQLAlchemy文档中进行了搜索,发现了两个潜在的线索,但似乎都不令人满意:

  • 使用Column.likeColumn.in_…:这些运营商都可以直接在列这将使其简单的使用getattr,但一些人仍下落不明(==>,等)。

  • 使用Column.op:例如,Cat.name.op('=')('Hobbes')但这似乎不适用于所有运算符(in即)。

有没有lambda功能的干净方法吗?


问题答案:

如果这对某人有用,这就是我最终要做的事情:

from flask import request

class Parser(object):

  sep = ';'

  # ...

  def filter_query(self, query):
    model_class = self._get_model_class(query) # returns the query's Model
    raw_filters = request.args.getlist('filter')
    for raw in raw_filters:
      try:
        key, op, value = raw.split(self.sep, 3)
      except ValueError:
        raise APIError(400, 'Invalid filter: %s' % raw)
      column = getattr(model_class, key, None)
      if not column:
        raise APIError(400, 'Invalid filter column: %s' % key)
      if op == 'in':
        filt = column.in_(value.split(','))
      else:
        try:
          attr = filter(
            lambda e: hasattr(column, e % op),
            ['%s', '%s_', '__%s__']
          )[0] % op
        except IndexError:
          raise APIError(400, 'Invalid filter operator: %s' % op)
        if value == 'null':
          value = None
        filt = getattr(column, attr)(value)
      query = query.filter(filt)
    return query

这涵盖了所有SQLAlchemy列比较器:

  • eq 对于 ==
  • lt 对于 <
  • ge 对于 >=
  • in 对于 in_
  • like 对于 like
  • 等等

详尽列表及其相应名称可在此处找到。



 类似资料:
  • 问题内容: 我刚刚开始使用SQLAlchemy。我决定使用它,因为我在sqlite查询中间使用了很多字符串表达式。 所以,这就是我的问题。我的桌子上有很多设备,每个设备都有维护级别的日期。关键是用户可以选择他想在屏幕上看到的维护级别。因此,我应该为他选择的每种维护级别组合“调整”我的SQLAlchemmy。 例如,在原始SQLite中。 SELECT * WHERE(设备IN [])和m_leve

  • 问题内容: 嗨,我想使用joinedload对查询进行过滤。但是我似乎无法使其正常工作。以下是我的示例查询 运行此命令时,它返回的行超出了我的期望。实际结果应仅返回8行。但是执行此查询后,它返回234行,这比我预期的要多 问题答案: 它不起作用的原因是(以及所有其他关系加载技术)是完全透明的。也就是说,在查询中包含a不会导致填充关系,而不会以任何其他方式影响它。您应该阅读“加入渴望的禅宗”,其开头

  • 问题内容: 在Flask-SQLAlchemy教程中,定义了User模型的构造函数: 对于具有两列的表,这可能是可以接受的,但是如果我有包含10列以上的表怎么办?每次定义新模型时 都 必须定义构造函数吗? 问题答案: 在大多数情况下,未在模型类中定义构造函数会为您提供正确的行为。 Flask- SQLAlchemy的基模型类(也是SQLAlchemy的声明性基类)定义了一个构造函数,该构造函数只接

  • 我想让我的子组件有一个ref,但是我不希望用户在创建组件时必须指定ref。所以说我有这样的东西: 我希望父组件能够访问子组件的状态。最简单的方法是为每个组件添加一个ref,但我希望这是在函数中完成的,以便从最终用户那里抽象出它,因为我希望这些组件被通用化。 有没有一种干净的方法可以让父组件访问子组件的状态,例如当创建子组件时,您有以下内容: 因此,在父类内部,我可以执行以下操作: 因此,我希望能够

  • 我正在构建API。我在弹性搜索中有身份证,名字,价格。客户机为我提供输入json和要应用的过滤器。 输入1:下面用户正在筛选ID=1(整数)的记录 输入2:用户正在查询带有city=tokyo的记录 用于处理输入和查询到弹性搜索的Java代码 对于过滤器中接收的每个键,我都在检查输入值的数据类型。 我想支持所有的专栏。我想要一个通用的解决方案,而不检查输入数据类型。 输入3: 在不对每个字段及其数

  • 问题内容: 我知道您可以通过提供,为SQLAlchemy的查询构建动态过滤器。 例如 以下是我的问题: 如果我需要通过“大于”或“小于”子句进行查询怎么办?例如(原始SQL): 问题答案: 我建议不要使用,而不是使用,它为您提供了更多选择。 例如(来自手册): 关于您的情况: