web-dev-qa-db-de.com

Python SQLAlchemy und Postgres - Wie fragt man ein JSON-Element ab?

Nehmen wir an, ich habe eine Postgres-Datenbank (9.3) und es gibt eine Tabelle mit dem Namen Resources. In der Tabelle Resources habe ich die Felder id, die ein int ist, und data, die ein JSON-Typ sind.

Nehmen wir an, ich habe die folgenden Datensätze in der Tabelle.

  • 1, {'Vorname': 'Dave', 'Nachname': 'Gallant'} 
  • 2, {'Vorname': 'John', 'Nachname': 'Doe'}

Was ich tun möchte, ist eine Abfrage zu schreiben, die alle Datensätze zurückgibt, in denen die Datenspalte ein Json-Element mit dem Nachnamen "Doe" enthält.

Ich habe versucht so etwas zu schreiben:

records = db_session.query(Resource).filter(Resources.data->>'lastname' == "Doe").all()

Pycharm gibt mir jedoch einen Kompilierungsfehler auf der "- >>"

Weiß jemand, wie ich die Filterklausel schreiben würde, um das zu tun, was ich brauche?

21
Dave Gallant

Versuchen Sie es mit astext

records = db_session.query(Resource).filter(
              Resources.data["lastname"].astext == "Doe"
          ).all()

Bitte beachten Sie, dass die Spalte MÜSSEN den Typ einer JSONB haben muss. Die reguläre JSON-Spalte funktioniert nicht.

37
Anzel

Sie können auch eine Zeichenfolge explizit in JSON umwandeln (siehe J98-Typ Postgres doc ). 

from sqlalchemy.dialects.postgres import JSON
from sqlalchemy.sql.expression import cast
db_session.query(Resource).filter(
    Resources.data["lastname"] == cast("Doe", JSON)
).all()
6
kc41

Gemäß sqlalchemy.types.JSON können Sie dies so machen

from sqlalchemy import JSON
from sqlalchemy import cast
records = db_session.query(Resource).filter(Resources.data["lastname"] == cast("Doe", JSON)).all()
0
user1900344