2015-04-30 9 views
11

Nehmen wir an, ich habe eine Postgres-Datenbank (9.3) und es gibt eine Tabelle namens Resources. In der Resources Tabelle habe ich die Felder id das ist ein int und data das ist ein JSON-Typ.Python SQLAlchemy und Postgres - Wie man ein JSON-Element abfragt

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

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

Was ich tun möchte, ist eine Abfrage schreiben, die so etwas wie dies alle Datensätze, in denen der Datenspalt hat ein json Element mit dem Nachnamen gleich „Doe“

ich habe versucht zu schreiben zurückkehren würden:

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

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

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

+0

Versuchen 'astext' wie: ein.' ... Filter (Resources.c.data [ "name"] ASTEXT == " Doe "). All()" und sehen, ob es funktioniert – Anzel

+0

Das scheint zu funktionieren, obwohl ich die ".c" entfernen musste und gehen Sie einfach "Resources.data" direkt. Vielen Dank! –

+0

Ah ... ja, ich gehe normalerweise mit '.c' für Spaltennamen ... froh, dass Sie es gelöst haben. Ich werde oben als Antwort dann posten :-) – Anzel

Antwort

20

Try astext

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

Große Antwort. Darüber hinaus bietet der von Ihnen angegebene Link auch einige weitere Informationen zum Abfragen von verschachteltem JSON (z. B. query.filter (Resources.data [("Nachname", "was auch immer-verschachtelt-json-unter-Nachname")]. Astext == "Whatever Value"). All()), und wie Datentypen geändert werden. –

5

Auch Sie könnten explizit werfen String zu JSON (siehe Postgres JSON type doc) verwenden.

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

Nach sqlalchemy.types.JSON, können Sie es tun, wie diese

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