2015-06-17 19 views
5

Oto aktualny indeks tworzenia kodu dla JSONB.Jak utworzyć indeks jsonb za pomocą GIN na SQLAlchemy?

Index("mytable_data_idx_id_key", Mytable.data['id'].astext, postgresql_using='gin') 

Ale mam ten błąd.

sqlalchemy.exc.ProgrammingError: (psycopg2.ProgrammingError) data type text has no default operator class for access method "gin" 
HINT: You must specify an operator class for the index or define a default operator class for the data type. 
[SQL: "CREATE INDEX event_data_idx_id_key ON event USING gin ((data ->> 'id'))"] 

Czy istnieje sposób na utworzenie indeksu na SQLAlchemy?

Odpowiedz

1

PostgreSQL docs specyficzny sqlalchemy w http://docs.sqlalchemy.org/en/latest/dialects/postgresql.html#operator-classes wspomnieć słownika postgresql_ops aby zapewnić „klasę operatora” używany przez PostgreSQL i zapewnić ten przykład ilustrujący jego zastosowanie:

Index('my_index', my_table.c.id, my_table.c.data, 
         postgresql_ops={ 
          'data': 'text_pattern_ops', 
          'id': 'int4_ops' 
         }) 

Od eksperymentowania, wydaje się, że trzeba użyj opisu indeksu text(), jeśli chcesz określić "klasę operatorów" dla indeksu wyrażeń. Więc

db.Index(
    'ix_sample', 
    sqlalchemy.text("(jsoncol->'values') jsonb_path_ops"), 
    postgresql_using="gin") 

... w __table_args__ dla modelu ORM określa indeks GIN na jsonb pola zawierającego tablicę ciągów, a to pozwala na efektywne wyszukiwań, czyli pasujące na każdy z ciągów w JSON pole tablica, która wygląda tak:

{ 
    "values": ["first", "second", "third"], 
    "other": "fields", 
    "go": "here" 
} 

Zapytania za pomocą operatora w PostgreSQL @> będzie wyglądać mniej więcej tak:

import sqlalchemy 
from sqlalchemy.dialects import postgresql 

query = session.query(MyModel).filter(
    sqlalchemy.type_coerce(MyModel.jsoncol['values'], postgresql.JSONB) 
    .contains(sqlalchemy.type_coerce("second", postgresql.JSONB))) 
results = query.all() 
+0

I TRIE d ale mam błąd. 'sqlalchemy.exc.ProgrammingError: (psycopg2.ProgrammingError) klasa operatora" text_pattern_ops "nie akceptuje typu danych jsonb' –

+0

zaktualizowałem swoją odpowiedź, podając więcej przykładów –