postgresql 使用Postgres和SQLAlchemy按JSON类型字段过滤

wooyq4lh  于 12个月前  发布在  PostgreSQL
关注(0)|答案(2)|浏览(283)

我有一个表test_table

Column     |          Type          |
------------+------------------------+
 id         | integer                |
 attributes | json                   |

字符串
含物:

id |    attributes
----+----------------------------
  1 | {"a": 1, "b": ["b1","b2"]}
  2 | {"a": 2, "b": ["b3"]}
  3 | {"a": 3}


我需要在attributes字段中按属性b过滤数据。
使用like方法,我找到了一个解决方案。

SELECT * FROM test_table
WHERE attributes ->> 'b' SIMILAR TO '%(b1|b3)%';
-- or using SQLAlchemy
arr = ["b1", "b3"]
arr = [f"%{i}%" for i in arr]
stmt = select(test_table).where(cast(t.c.attributes["b"], String).like(any_(arr)))


其结果是:

id |    attributes
----+----------------------------
  1 | {"a": 1, "b": ["b1","b2"]}
  2 | {"a": 2, "b": ["b3"]}


但我仍在努力寻找这样的解决方案

SELECT * FROM test_table 
WHERE attributes -> 'b' ?| array['b1', 'b3'];


使用纯SQLAlchemy是否可以实现这一点?
邮政总局9.6
SQLAlchemy 1.4版

f0ofjuux

f0ofjuux1#

使用纯SQLAlchemy是否可以实现这一点?
实际上,它与您想象的几乎完全一样。

SELECT * FROM test_table 
WHERE attributes::jsonb -> 'b' ?| array['b1', 'b3'];

字符串
在纯SQLAlchemy中,您可以同样地使用cast(),而?|运算符将转换为.has_any()

arr = ["b1", "b3"]
stmt = select(test_table).where(cast(t.c.attributes["b"],JSONB).has_any(arr))


有一张table有其他的翻译。
JSONPath会更灵活,但SQLAlchemy 1.4支持它,而PostgreSQL 9.6不支持-您需要12.0或更高版本。

798qvoo8

798qvoo82#

在SQLAlchemy中,处理JSON数据可能有点棘手,特别是在基于JSON字段中的条件进行查询时。
如果您使用的是SQLAlchemy 1.4或更高版本,则可以按以下方式完成此操作:

from sqlalchemy import select, func
from sqlalchemy.dialects.postgresql import JSONB

# Assuming test_table is your Table object and 'attributes' is the column
stmt = select(test_table).where(
    func.jsonb_exists_any(
        cast(test_table.c.attributes['b'], JSONB),
        array(['b1', 'b3'])
    )
)

字符串

相关问题