web-dev-qa-db-fra.com

Utilisation du type JSON avec Flask-sqlalchemy & Postgresql

Contexte: Je construis une Flask App et j'ai stocké mes données dans une base de données postgresql et dans un type de colonne JSON.

Tâche: Dans mes fonctions d'affichage, je voudrais commander une requête de base de données par {Key: Value} dans la colonne JSON

Accomplished: J'ai réussi à effectuer cette requête sur la ligne de commande psql en utilisant la commande suivante par exemple:

sélectionnez * à partir de la cible où cast (produit - >> 'profit' comme flottant)> 100 ordre par cast (produit - >> 'salesrank' comme entier) asc;

Problème: Je ne peux pas répliquer cette requête dans mon code (voir le code du modèle ci-dessous dans la section Info supplémentaire)

from app import app, db
from models import Target 

data = Target.query.order_by(Target.product['salesrank'])

Erreur reçue - ProgrammingError: (ProgrammingError) n'a pas pu identifier un opérateur de commande pour le type json LIGNE 2: FROM cible ORDER BY target.product -> 'salesrank' ^ CONSEIL: Utilisez un opérateur de commande explicite ou modifiez le requete. 'SELECT target.id AS target_id, target.store AS target_store, target.product AS target_product, target.asin AS target_asin, target.date AS target_date\nFROM target ORDER BY target.product ->% (product_1) s\n LIMIT% (param_1) s '{' product_1 ':' salesrank ',' param_1 ': 1}

Extra Info Mon modèle cible a été configuré comme tel:

#models.py
from app import db
from sqlalchemy.dialects.postgresql import JSON
import datetime

class Target(db.Model):
    __tablename__ = 'target'

    id = db.Column(db.Integer)
    store = db.Column(db.String())
    product = db.Column(JSON)
    asin = db.Column(db.String(), primary_key=True)
    date = db.Column(db.DateTime, default=datetime.datetime.utcnow())

Mon fichier App.py où je définis Flask et Sqlalchemy

from flask import Flask
import os
from flask.ext.sqlalchemy import SQLAlchemy
from flask_bootstrap import Bootstrap

app = Flask(__name__)
app.config.from_object(os.environ['APP_SETTINGS'])
db = SQLAlchemy(app)
Bootstrap(app)

import views
from app import app
from models import Result

if __name__ == '__main__':
    app.run(Host='192.168.1.5', port=5000, debug=True)

Merci pour toute aide que vous pouvez fournir!

26
larrywgray

En regardant la documentation SQLAlchemy pour le type de données JSON il semble que vous devriez pouvoir utiliser le .cast méthode:

from sqlalchemy.types import Integer

from app import app, db
from models import Target 

# SQLAlchemy 1.1+
data = Target.query.order_by(Target.product['salesrank'].astext.cast(Integer))

# SQLAlchemy < 1
data = Target.query.order_by(Target.product['salesrank'].cast(Integer))
21
Sean Vieira