基于单个字符串的 Postgres JSON 列表对象上的 Flask SQLAlchemy 过滤器
Flask SQLAlchemy Filter On A Postgres JSON List Object Based on a Single String
我有一个名为测试的模型。名为 alias
的字段是一个 JSON 字段(实际上是一个列表)并且具有 ["a", "b"]
或 ["d", "e"]
等值。
class Testing(db.Model):
__tablename__ = 'testing'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(25))
alias = db.Column(JSON)
def __init__(self, name, alias):
self.name = name
self.alias = alias
在我的 flask 视图中,我获取了一个 url 参数,我想用它来过滤 Testing 以获取参数值在 alias
json 列表中的所有 Testing 对象.因此,例如,如果 url_param_value="a"
我想要 "a"
在 alias
中的所有测试对象。因此,["a", "b"]
的 alias
值在此示例中将成为命中。
这是我的方法,但它不起作用,我认为它与序列化有关。
Testing.query.filter(Testing.alias.contains(url_param_val)).all()
我收到以下错误
NotImplementedError: Operator 'contains' is not supported on this expression
name
字段是JSON类型,不是数组类型。 JSON 列没有 contains
方法,即使您恰好存储数组数据(数据库怎么知道?)
在 Postgres 中,您可以使用 json_array_elements
将 JSON 数组扩展为一组 JSON 值;这将 return 每个元素一行:
select id, json_array_elements(alias) as val from testing;
id | val
---------+--------------------
1 | "a"
2 | "b"
您可以将其用作 select 包含匹配值的记录的子查询:
select t.id, t.name, t.alias, cast(q.val as varchar)
from testing t, (
select id, json_array_elements(alias) as val
from testing
) q
where q.id=t.id and cast(q.val as varchar) = '"a"';
在 SQLAlchemy 语法中:
subq = session.query(
Testing.id,
func.json_array_elements(Testing.alias).label("val")
).subquery()
q = session.query(Testing).filter(
cast(subq.c.val, sa.Unicode) == '"a"',
subq.c.id == Testing.id)
警告:这对于大表来说效率非常低;您最好修复类型以匹配您的数据,然后创建适当的索引。
我有一个名为测试的模型。名为 alias
的字段是一个 JSON 字段(实际上是一个列表)并且具有 ["a", "b"]
或 ["d", "e"]
等值。
class Testing(db.Model):
__tablename__ = 'testing'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(25))
alias = db.Column(JSON)
def __init__(self, name, alias):
self.name = name
self.alias = alias
在我的 flask 视图中,我获取了一个 url 参数,我想用它来过滤 Testing 以获取参数值在 alias
json 列表中的所有 Testing 对象.因此,例如,如果 url_param_value="a"
我想要 "a"
在 alias
中的所有测试对象。因此,["a", "b"]
的 alias
值在此示例中将成为命中。
这是我的方法,但它不起作用,我认为它与序列化有关。
Testing.query.filter(Testing.alias.contains(url_param_val)).all()
我收到以下错误
NotImplementedError: Operator 'contains' is not supported on this expression
name
字段是JSON类型,不是数组类型。 JSON 列没有 contains
方法,即使您恰好存储数组数据(数据库怎么知道?)
在 Postgres 中,您可以使用 json_array_elements
将 JSON 数组扩展为一组 JSON 值;这将 return 每个元素一行:
select id, json_array_elements(alias) as val from testing;
id | val
---------+--------------------
1 | "a"
2 | "b"
您可以将其用作 select 包含匹配值的记录的子查询:
select t.id, t.name, t.alias, cast(q.val as varchar)
from testing t, (
select id, json_array_elements(alias) as val
from testing
) q
where q.id=t.id and cast(q.val as varchar) = '"a"';
在 SQLAlchemy 语法中:
subq = session.query(
Testing.id,
func.json_array_elements(Testing.alias).label("val")
).subquery()
q = session.query(Testing).filter(
cast(subq.c.val, sa.Unicode) == '"a"',
subq.c.id == Testing.id)
警告:这对于大表来说效率非常低;您最好修复类型以匹配您的数据,然后创建适当的索引。