在 sqlalchemy python 中构建动态过滤器

Posted

技术标签:

【中文标题】在 sqlalchemy python 中构建动态过滤器【英文标题】:build dynamic filters in sqlalchemy python 【发布时间】:2016-08-25 06:13:27 【问题描述】:

我需要使用动态列及其值动态生成/构建 sqlalchemy 查询。

示例 - 我在 SQL 中有一个名为“Convo”的表,它有类似的列 - UserID、ConvoID、ConvoID。

我需要根据以下条件获取行。

criteria = (('UserID', 2), ('ConvoID', 1) ,('ContactID', 353))

我为此使用了“烘焙查询”逻辑。但是有些我无法成功运行此查询。

下面是我的代码。

criteria = (('UserID', 2), ('ConvoID', 1) ,('ContactID', 353))
baked_query = bakery(lambda session: session.query(tablename))
for key1 in condition:
    baked_query += lambda q: q.filter(tablename.key1 == condition[key1])
    result = baked_query(self.session).all()

我收到错误 -

AttributeError: type object 'Convo' has no attribute 'key1'

请帮我解决这个问题

【问题讨论】:

您可能想要getattr(tablename, key1) 而不是tablename.key1 【参考方案1】:
criteria = (('UserID', 2), ('ConvoID', 1) ,('ContactID', 353))

query = session.query(tablename)
for _filter, value in criteria:
    query = query.filter(getattr(tablename, _filter) == value)
result = query.all()

【讨论】:

【参考方案2】:

如果您使用动态键和“简单”相等检查,filter_by 方法可能更方便,因为它采用与您的属性名称匹配的关键字参数并将其组装到 where 子句中。

所以您的迭代查询构造可能如下所示:

baked_query = bakery(lambda session: session.query(tablename))
for key, value in condition.items():
    baked_query += lambda q: q.filter_by(key=value)

另外,由于 filter_by 采用多个关键字参数,您可以将查询构造简化为单个 filter_by 调用:

baked_query = bakery(lambda session: session.query(tablename))
baked_query += lambda q: q.filter_by(**condition)

以上所有内容显然都假设您的 condition 变量引用了字典。

【讨论】:

以上是关于在 sqlalchemy python 中构建动态过滤器的主要内容,如果未能解决你的问题,请参考以下文章

使用 SQLAlchemy 基于类自动构建数据库表

SQLAlchemy 查询 - 动态类选择

SqlAlchemy:动态查询

使用python操作RabbitMQ,Redis,Memcache,SQLAlchemy 其二

使用 Python 的 Sqlalchemy 和 Singlestore sql 创建类似于现有的表

在 Flask 中构建带有动态元素的 Bootstrap 表