web-dev-qa-db-fra.com

Python SQLAlchemy and Postgres - Comment interroger un élément JSON

Disons que j'ai une base de données Postgres (9.3) et qu'il existe une table appelée Resources. Dans la table Resources, j'ai les champs id qui est un int et data qui est un type JSON.

Disons que j'ai les enregistrements suivants dans ledit tableau.

  • 1, {'prénom': 'Dave', 'nom': 'Gallant'} 
  • 2, {'prénom': 'John', 'nom': 'Doe'}

Ce que je veux faire, c'est écrire une requête qui renverrait tous les enregistrements dans lesquels la colonne de données a un élément json avec le nom de famille égal à "Doe"

J'ai essayé d'écrire quelque chose comme ça:

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

Pycharm me donne cependant une erreur de compilation sur le "- >>"

Est-ce que quelqu'un sait comment j'écrirais la clause de filtrage pour faire ce dont j'ai besoin?

21
Dave Gallant

Essayez d’utiliser astext

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

Veuillez noter que la colonne DOIT avoir le type d'un JSONB. La colonne JSON normale ne fonctionnera pas.

37
Anzel

Vous pouvez aussi explicitement convertir la chaîne en JSON (voir Postgres, type JSON 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

Selon sqlalchemy.types.JSON , vous pouvez le faire comme ceci

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