You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将含jsonb_each_text的PostgreSQL语句转为Django ORM查询?

解决Django ORM调用PostgreSQL jsonb_each_text展开JSONB字段的问题

目标是把这条PostgreSQL语句转成Django ORM查询:

SELECT s.id, jsonb_each_text.key, jsonb_each_text.value 
FROM survey as s, jsonb_each_text(s.answers);

直接可行的方案:使用RawQuerySet

这是最直接的方式,完全复用原生SQL,避开ORM对函数生成表的限制:

from django.db.models import RawQuerySet

# 执行原生查询
results = Survey.objects.raw("""
    SELECT s.id, jsonb_each_text.key, jsonb_each_text.value
    FROM survey as s, jsonb_each_text(s.answers)
""")

# 遍历结果
for item in results:
    print(item.id, item.key, item.value)

基于ORM的优化方案:结合Lateral Join(Django 1.11+)

如果想保留ORM的灵活性,可以用Django支持的Lateral Join配合自定义函数:

from django.db.models import Func, F, Lateral
from django.db.models.fields import TextField, SlugField

# 定义jsonb_each_text函数
class JsonbEachText(Func):
    function = 'jsonb_each_text'
    # 声明输出字段的结构
    output_fields = [
        ('key', SlugField()),
        ('value', TextField()),
    ]

# 构建Lateral关联查询
answers_lateral = Lateral(
    JsonbEachText(F('answers')).values('key', 'value')
)

# 关联Survey表并查询
survey_results = Survey.objects.annotate(
    key=F('answers_lateral__key'),
    value=F('answers_lateral__value'),
).select_related('answers_lateral')

修复你用第三方库的问题

你之前用的第三方库报错,核心问题是JsonbEachText的模板里加了单引号,导致把s.answers当成字符串而非字段引用,修正后即可正常使用:

class JsonbEachText(models.Func):
    function = 'jsonb_each_text'
    # 去掉单引号,让表达式作为字段引用
    template = "%(function)s(%(expressions)s)"
    output_fields = [
        ('key', models.SlugField()),
        ('value', models.TextField()),
    ]

class JsonbTable(DynamicFromClauseBaseModel):
    EXPRESSION_CLASS = JsonbEachText

    key = models.SlugField(primary_key=True)
    value = models.TextField()
    survey_id = models.IntegerField()

# 使用F表达式引用Survey的answers字段,而非字符串
result = JsonbTable.objects.fill_expression_with_parameters(
    F('survey.answers')
).join(Survey, survey_id=Survey.id)

内容的提问来源于stack exchange,提问作者rgilligan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 09:55:22