我想检查特定的电子邮件模板是否在任何其他模型实例和模型规则中使用,我们在运行下面的查询时有操作(JSONB),但出现错误
我添加了示例查询和错误响应
操作栏响应结构示例
{
"negative": [],
"positive": [
{
"action": 45,
"email_template_id": 1
}
]
}
查询查看email_template
event_exists_subquery = exists().where(Event.email_template_id == EmailTemplate.id)
subquery = exists().where(
or_(
func.jsonb_contains(
Rule.actions["positive"],
func.jsonb(literal({"email_template_id": EmailTemplate.id})),
),
func.jsonb_contains(
Rule.actions["negative"],
func.jsonb(literal({"email_template_id": EmailTemplate.id})),
),
)
)
statement = select(
EmailTemplate.id,
EmailTemplate.name,
case((or_(event_exists_subquery, subquery), False), else_=True).label("is_used"),
)
email_templates = (await request.state.db.execute(statement)).mappings().all()
错误响应示例
sqlalchemy.exc.ProgrammingError: (psycopg.ProgrammingError) cannot adapt type 'dict' using placeholder '%s' (format: AUTO)
[SQL: SELECT email_templates.id, email_templates.name, CASE WHEN (EXISTS (SELECT *
FROM events
WHERE events.email_template_id = email_templates.id)) THEN %(param_1)s ELSE %(param_2)s END AS is_editable, CASE WHEN (EXISTS (SELECT *
FROM rules
WHERE jsonb_contains((rules.actions -> %(actions_1)s::TEXT), jsonb(%(param_3)s)) OR jsonb_contains((rules.actions -> %(actions_2)s::TEXT), jsonb(%(param_4)s)))) THEN %(param_5)s ELSE %(param_6)s END AS is_used
FROM email_templates
WHERE email_templates.deleted_at IS NULL]
[parameters: {'param_1': False, 'param_2': True, 'actions_1': 'positive', 'param_3': {'email_template_id': <sqlalchemy.orm.attributes.InstrumentedAttribute object at 0x115d52ca0>}, 'actions_2': 'negative', 'param_4': {'email_template_id': <sqlalchemy.orm.attributes.InstrumentedAttribute object at 0x115d52ca0>}, 'param_5': False, 'param_6': True}]
我有以下包裹:
数据库:Postgres
我也尝试了以下方法来解决相同但出现相同类型的错误
subquery = exists().where(
or_(
Rule.actions["positive"].contains(
[{"email_template_id": email_template_id}]
),
Rule.actions["negative"].contains(
[{"email_template_id": email_template_id}]
),
)
)
您可以让 Postgres 使用
jsonb_build_object
函数来完成此操作,而不是尝试在 SQLAlchemy 中构建 JSON 文字,其工作原理如下:
so# select jsonb_build_object('a', 1, 'b', 2);
jsonb_build_object
════════════════════
{"a": 1, "b": 2}
在您的代码中,您的条件可能如下所示:
import sqlalchemy as sa
...
subquery = sa.exists().where(
sa.or_(
sa.func.jsonb_contains(
Rule.actions["positive"],
sa.func.jsonb_build_object("email_template_id", EmailTemplate.id),
),
sa.func.jsonb_contains(
Rule.actions["negative"],
sa.func.jsonb_build_object("email_template_id", EmailTemplate.id),
),
)
)