jsonb 문자열 목록에 대한 Postgresql SQLalchemy 필터 쿼리

Aug 18 2020

SQLalchemy를 처음 사용하고 Postgresql을 사용하는 초보자이므로 용서하십시오.

다음과 같은 진 인덱싱 된 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)

답변

1 snakecharmerb Aug 18 2020 at 20:28

다음 과 같이 에서 필요한 has_key표현식을 만들 수 있습니다 or_.

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])

산출:

['AAAA', 'CCCC']