在 Flask-sqlalchemy 和 Postgresql 中使用 JSON 类型

Posted

技术标签:

【中文标题】在 Flask-sqlalchemy 和 Postgresql 中使用 JSON 类型【英文标题】:Using JSON Type with Flask-sqlalchemy & Postgresql 【发布时间】:2014-07-15 16:42:45 【问题描述】:

背景:我正在构建一个 Flask 应用程序,并且我已将我的数据存储到一个 postgresql 数据库和一个 JSON 列类型中。

任务:在我的视图函数中,我想通过 JSON 列中的 Key:Value 订购数据库查询

已完成:我已成功在 psql 命令行中执行此查询,例如使用以下命令:

select * from target where cast(product->>'profit' as float) > 100 order by cast(product->>'salesrank' as integer) asc;

问题:我无法在我的代码中复制此查询(请参阅下面额外信息部分中的模型代码)

from app import app, db
from models import Target 

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

收到错误 - ProgrammingError: (ProgrammingError) 无法识别 json 类型的排序运算符 第 2 行:从目标 ORDER BY target.product -> 'salesrank' ^ 提示:使用显式排序运算符或修改查询。 '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

额外信息 我的目标模型是这样设置的:

#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())

我定义 Flask 和 Sqlalchemy 的 App.py 文件

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)

感谢您提供的任何帮助!

【问题讨论】:

虽然有点不相关。我遇到了 JSON 问题,但不是查询问题,而是数据的初始插入问题。您知道如何将数据插入 JSON 字段吗?有关更多详细信息,请参阅我的问题。 ***.com/questions/55628358/… 【参考方案1】:

查看the SQLAlchemy documentation for the JSON data type 看来您应该可以使用.cast 方法:

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))

【讨论】:

我在文档中遇到过这个问题,之前尝试过几次,但只得到“整数”未知错误 --- 我现在意识到我只需要从 sqlalchemy.dialects.postgresql 导入 INTEGER 即可这行得通。正确的代码是: 或您建议的来自 sqlalchemy.types 的整数以使其正常工作。 自 1.1 版以来,JSONElement.cast() 快​​捷方式消失了:“在 1.1 版中更改:JSON 对象上的 ColumnElement.cast() 运算符现在要求显式调用 JSON.Comparator.astext 修饰符,如果强制转换仅适用来自文本字符串。”

以上是关于在 Flask-sqlalchemy 和 Postgresql 中使用 JSON 类型的主要内容,如果未能解决你的问题,请参考以下文章

flask-sqlalchemy:数据未更新[重复]

Flask-SQLAlchemy 和 SQLAlchemy

在 Flask-sqlalchemy 和 Postgresql 中使用 JSON 类型

Flask-SQLAlchemy:用户角色模型和关系

Flask-SQLAlchemy安装及设置

Flask-SQLAlchemy安装及设置