2017-07-04 1 views
0

SQLAlchemyの - Iは、以下のSQLクエリを作成する必要が照会及びフィルタリングネストさjsonbフィールド

SELECT 
    distinct entity.id, 
    item_keys 
FROM entity 
    jsonb_each(entity.jsonb) item, -- extracts first level 
    jsonb_each(entity.value) as item_values, -- extracts keys from first level 
    jsonb_array_elements(item_values.value) item_keys -- 
WHERE 
item_keys->>'key' = 'somevalue'; 

私は列に格納されているネストされたJSONを有するので、私はそれらに対して列挙された値とフィルタを抽出する必要があります

{"filters": 
    {"first_filter": [{"end": "100", "begin": "1"}], 
    {"second_filter": [{"end": "4095", "begin": "1"}] 
} 

現在、私は次のように使用することができます。

次QUを生成
fields = [entity.c.id.label('id'), entity.c.jsonb.label('jsonb')] 

n1 = (Grouping(func.jsonb_each(entity.c.jsonb)).op('.')(literal_column('value')).label('level1')) 
n2 = (Grouping(func.jsonb_each(n1)).op('.')(literal_column('value')).label('level2')) 
filter_value = (Grouping(func.jsonb_array_elements(n2)).label('filter_value')) 

filter_sql = select([filter_value]).alias('filters') 

sql = select(fields, distinct=True).select_from(filter_value) 
sql.where(literal_column(filter.value).op('->>')('key') == 'value') 

エリ:

SELECT 
    DISTINCT entity.id AS entity_id, 
    companies_company.slug AS slug 
    et.work_hours_time_ranges AS schedule_set_work_hours_time_ranges 
FROM 
entity, 
(SELECT 
    (jsonb_array_elements(
     (jsonb_each(
      (jsonb_each(entity.jsonb)) . value) 
     ) . value) 
    ) AS filter_value FROM entity) AS filters 
WHERE 
filter.filter_value ->> 'key' <= 'value'; 

そして、無効な結果 - エンティティを倍増します。

+0

生成されたクエリは、指定されたPythonではマッチしないようです。 –

+0

[FunctionElement.alias() '](http://docs.sqlalchemy.org/en/latest/core/functions.html#sqlalchemy.sql.functions.FunctionElement.alias)を使用すると、クエリ構築。 –

答えて

-2

いつものように、できるだけ早く私は句1つの以上のサブクエリFROMので質問私は自分自身で答えを見つけること:)

を投稿するよう、私も主節でそれに参加する必要があります。

fields = [entity.c.id.label('id'), entity.c.jsonb.label('jsonb')] 

n1 = (Grouping(func.jsonb_each(entity.c.jsonb)).op('.')(literal_column('value')).label('level1')) 
n2 = (Grouping(func.jsonb_each(n1)).op('.')(literal_column('value')).label('level2')) 
filter_value = (Grouping(func.jsonb_array_elements(n2)).label('filter_value')) 

filter_sql = select([entity.c.id, filter_value]).alias('filters') 

sql = select(fields, distinct=True).select_from(filter_value) 
sql.where(and_([ 
    (literal_column(filter.value).op('->>')('key') == 'value'), 
    (literal_column('filters.id') == entity.c.id), 
])) 

そしてすべてが期待どおりに動作するようになりました。

+0

SQLAlchemy 1.1.9では、例外が発生します。ArgumentError:FROM式が必要です。 –

+0

@IljaEverilä私は実際にクエリの半分を削除して少し単純化しました。おそらく、間違いを起こしました。気にしないで。私は実際問題を自分で考え出した。 :) – bosha

関連する問題