繁体   English   中英

Postgresql SQLalchemy 过滤查询 jsonb 字符串列表

[英]Postgresql SQLalchemy filter query for list of jsonb strings

请原谅我,因为我是 SQLalchemy 的新手,还是 Postgresql 的初学者。

我有一个 gin 索引的 jsonb 字符串列,如下所示:

my_id| my_column
0    | "AAAA"
1    | "BBBB"
2    | "CCCC"

我需要在“my_column”中搜索“AAAA”和“CCCC”,因为我只收到这个字符串。 这应该在没有 for 循环的情况下更好地完成,因为有数百个这样的字符串。 'my_column' 属于表 'my_table'。 “my_id”列是主键。 仅针对“AAAA”的显式 sql 查询将是:

select * from my_table
where my_column ? 'AAAA'

使用 SQLalchemy,对此的查询将在 python 中,类似于:

from sqlalchemy import create_engine, Column, Integer
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.dialects.postgresql import JSONB

Base = declarative_base()

class my_class(Base):
__tablename__ = 'my_table'
my_id     =  Column(Integer, primary_key=True)
my_column =  Column(JSONB)

engine = create_engine('postgresql+psycopg2://user:pass@host/db')
session = sessionmaker(bind=engine)()

session.query(my_class).filter(my_class.my_column.has_key("AAAA").all()

我知道可以使用 in 子句查询整数列表,如下所示:

session.query(my_class).filter(my_class.example_id.in_((123,456))).all()

但是我没有像这样使用成功:

session.query(my_class).filter(my_class.my_column.in_(('AAAA','CCCC'))).all()

有没有办法在不使用循环的情况下查询 jsonb 列中的字符串列表? 是否可以只输入一个包含所有字符串的类似列表的参数,而无需像这样显式键入我要搜索的所有字符串:

session.query(my_class).filter(my_class.my_column.in_(([list_full_of strings]))).all()

编辑:

从查询:

session.query(my_class).filter(my_class.my_column.in_(('AAAA','CCCC'))).all()

出现以下错误:

sqlalchemy.exc.DataError: (psycopg2.errors.InvalidTextRepresentation) invalid input syntax for type json
LINE 3: WHERE my_table.my_column IN ('AAAA', 'CCCC')
                                        ^
DETAIL:  Token "AAAA" is invalid.
CONTEXT:  JSON data, line 1: AAAA...

[SQL: SELECT my_table.my_id AS my_table_my_id, my_table.my_column AS my_table_my_column
FROM my_table
WHERE my_table.my_column IN (%(my_column_1)s, %(my_column_2)s)]
[parameters: {'my_column_1': 'AAAA', 'my_column_2': 'CCCC'}]
(Background on this error at: http://sqlalche.me/e/13/9h9h)

您可以在or_ has_key ,如下所示:

keys = ['AAAA', 'CCCC'] 
clauses = [my_class.my_column.has_key(k) for k in keys]  
recs = session.query(my_class).filter(sqlalchemy.or_(*clauses)).all()  
print([r.my_column for r in recs])

Output:

['AAAA', 'CCCC']

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM