2015-01-29 18 views
5

iç içe anahtarlara göre filtrelenmiş. Bazen yuvalanmış anahtarlara sahip bir JSONB alanı var. Örnek: Ben .filter(TestMetadata.metadata_item.has_key(nested_field))
yaparsanızSQLAlchemy süzgeci JSONB

{"nested_field": {"another URL": "foo", "a simple text": "text"}, "first_metadata": "plain string", "another_metadata": "foobar"}

Ben bu kaydı olsun.

İç içe geçmiş anahtarın varlığını nasıl arayabilirim? ("a simple text") ? operator ile iç içe alanın varlığı için

cevap

10

test dize için çalışmalıdır:

SQLAlchemy documentation of JSONB uyarınca
class TestMetadata(Base): 
    id = Column(Integer, primary_key=True) 
    name = Column(String) 
    metadata_item = Column(JSONB) 

(Yol dizin işlemleri örnek bulun):

expr = TestMetadata.metadata_item[("nested_field", "a simple text")] 
q = (session.query(TestMetadata.id, expr.label("deep_value")) 
    .filter(expr != None) 
    .all()) 

aşağıda SQL oluşturmak gereken:

SELECT testmetadata.id AS testmetadata_id, 
     testmetadata.metadata_item #> %(metadata_item_1)s AS deep_value 
FROM testmetadata 
WHERE (testmetadata.metadata_item #> %(metadata_item_1)s) IS NOT NULL 
-- @params: {'metadata_item_1': u'{nested_field, a simple text}'} 
+4

Awesom e ... IMHO, Path indeksinin yuvalanmış bir JSON olduğu net değil, ama belki de sadece benim. Bu arada - bir değeri kontrol etmek için kullanmak istiyorum: '.filter (TestMetadata.metadata_item [anahtar] .astext == value)' Anahtar nerede tuple – Boaz

+1

Elbette, ben senin soruydu * Daha fazla * varlığı kontrol edin * ve değil * değeri kontrol edin * şey türünü. – van

+1

Tamamen haklısın ... İkisine de ihtiyacım vardı (ve görünüşe göre impl. Farklıdır çünkü has_key bir tuple desteklemiyor) – Boaz

1

Bu sorgu testleri, -> operator ile iç içe JSON nesnesi ayıklanması sonra: Düz CİN endeksi bu sorguyu desteklemediği

SELECT EXISTS (
    SELECT 1 
    FROM testmetadata 
    WHERE metadata_item->'nested_field' ? 'a simple text' 
    ); 

Not. Bunu hızlı yapmak için numaralı telefondan expression index'a ihtiyacınız vardır.

CREATE INDEX testmetadata_special_idx ON testmetadata 
USING gin ((metadata_item->'nested_field')); 

benzer vaka için example in the manual yoktur. Sqlalchemy ile