【发布时间】:2021-10-29 23:11:22
【问题描述】:
我正在尝试找出使用 json_each 的正确方法。我见过一些技巧,比如使用column 或text。到目前为止,我已经找到了一种使用table_valued 的非常干净的方法,除了交叉连接警告之外,它可以工作。
term = 'connection'
about_exp = func.json_each(EventHistory.event, '$.about').table_valued('value')
events = s.query(EventHistory).filter(about_exp.c.value == term)
EventHistory 包含一个 json 字段,如下所示:{"about": ["antenna", "connection", "modem", "network"]}
生成的查询按预期工作,但我收到以下警告: SAWarning:SELECT 语句在 FROM 元素“event_history”和 FROM 元素“anon_1”之间有一个笛卡尔积。在要解析的每个元素之间应用连接条件。
对于任何想在这里进行实验的人来说,这是一个来自单元测试的工作示例:https://gist.github.com/PiotrCzapla/579f76bdf95a485eaaafed1492d9a70e
【问题讨论】:
-
为什么不使用原始查询?
-
这是一个简化的示例,我希望能够与其他实体连接并为此使用 sqlalchemy 隐式连接。但使用文本是其中一种选择。
-
我认为您加入或尝试使用最新 SQL 功能的实体越多,sqlalchemy 代码就越神秘和模糊。在我看来,当您以专有的命令式方式表达声明性逻辑(并且有一个非常好的标准)时,这似乎很自然。为什么要这样做?顺便说一句,在这种特殊情况下,根本不需要连接。
select <whatever> from "EventHistory" where "event"::jsonb @> '{"about":["connection"]}' -
@> 操作真的很酷,谢谢。它在 sqlalchemy 中也得到了很好的表达。我的实际代码需要选择 json_each,因此我没有考虑替代表达式,但谢谢!随时添加此作为答案以获得投票。
标签: json postgresql sqlalchemy