SQLAlchemy:查询包含数组和计数匹配项的 JSON 列 (PostgreSQL)
SQLAlchemy: Query a JSON column (PostgreSQL) containing array and counting matches
我对 SQLAlchemy 有点陌生,在数据库中使用 JSON 列。
我的数据库模型
from sqlalchemy.dialects.postgresql import JSON
class Traydetails(db.Model):
id= db.Column(db.Integer, autoincrement=True, primary_key=True)
traynumber = db.Column(db.String, unique=True)
safety_data = db.Column(JSON)
我的JSON结构
[{"Formulation": "Form1", "Hazard Rating": "Class B"}, {"Formulation": "Form2", "Hazard Rating": "Class B"}, {"Formulation": "Form3", "Hazard Rating": "Class B"}, {"Formulation": "Form4", "Hazard Rating": "Class B"}, {"Formulation": "Form5", "Hazard Rating": "Class B"}, {"Formulation": "Form6", "Hazard Rating": "Class B"}, {"Formulation": "Form7", "Hazard Rating": "Class B"}, {"Formulation": "Form8", "Hazard Rating": "Class B"}, {"Formulation": "Form9", "Hazard Rating": "Class B"}, {"Formulation": "Form10", "Hazard Rating": "Class B"}]
已尝试查询 1
hazard = Traydetails.query.filter(Traydetails.safety_data['Hazard Rating'].astext == "Class B").count()
它returns没什么。
已尝试查询 2
hazard = Traydetails.query.filter(Traydetails.safety_data[0]['Hazard Rating'].astext.cast(Unicode) == "Class B").count()
它returns只有一个(因为我比较的是一个位置)
但我的目标是计算危险等级(关键)中有多少 class B。
注意会有不同类型的 classes 像 Class A , Class B , class N.
您可以使用 postgres 函数 json_array_elements
形成一个子查询,您可以对其进行过滤以检索 Class B
危险等级的计数:
from sqlalchemy import func
subq = session.query(func.json_array_elements(Traydetails.safety_data).label('safety_data')).subquery()
count = session.query(subq).filter(subq.c.safety_data.op('->>')('Hazard Rating') == 'Class B').count()
print(count)
filter
正在使用子查询的 safety_data 标记列:subq.c.safety_data
。对于 .op
,我们使用自定义运算符 ->>
,它将 json 转换为文本。有关运算符的详细信息,请参阅 the docs。
我对 SQLAlchemy 有点陌生,在数据库中使用 JSON 列。
我的数据库模型
from sqlalchemy.dialects.postgresql import JSON
class Traydetails(db.Model):
id= db.Column(db.Integer, autoincrement=True, primary_key=True)
traynumber = db.Column(db.String, unique=True)
safety_data = db.Column(JSON)
我的JSON结构
[{"Formulation": "Form1", "Hazard Rating": "Class B"}, {"Formulation": "Form2", "Hazard Rating": "Class B"}, {"Formulation": "Form3", "Hazard Rating": "Class B"}, {"Formulation": "Form4", "Hazard Rating": "Class B"}, {"Formulation": "Form5", "Hazard Rating": "Class B"}, {"Formulation": "Form6", "Hazard Rating": "Class B"}, {"Formulation": "Form7", "Hazard Rating": "Class B"}, {"Formulation": "Form8", "Hazard Rating": "Class B"}, {"Formulation": "Form9", "Hazard Rating": "Class B"}, {"Formulation": "Form10", "Hazard Rating": "Class B"}]
已尝试查询 1
hazard = Traydetails.query.filter(Traydetails.safety_data['Hazard Rating'].astext == "Class B").count()
它returns没什么。
已尝试查询 2
hazard = Traydetails.query.filter(Traydetails.safety_data[0]['Hazard Rating'].astext.cast(Unicode) == "Class B").count()
它returns只有一个(因为我比较的是一个位置)
但我的目标是计算危险等级(关键)中有多少 class B。 注意会有不同类型的 classes 像 Class A , Class B , class N.
您可以使用 postgres 函数 json_array_elements
形成一个子查询,您可以对其进行过滤以检索 Class B
危险等级的计数:
from sqlalchemy import func
subq = session.query(func.json_array_elements(Traydetails.safety_data).label('safety_data')).subquery()
count = session.query(subq).filter(subq.c.safety_data.op('->>')('Hazard Rating') == 'Class B').count()
print(count)
filter
正在使用子查询的 safety_data 标记列:subq.c.safety_data
。对于 .op
,我们使用自定义运算符 ->>
,它将 json 转换为文本。有关运算符的详细信息,请参阅 the docs。