Django 3.2+MariaDB中JSONField嵌套数组对象查询无结果问题
解决Django 3.2 + MariaDB下JSONField嵌套数组的查询问题
问题原因
Django 3.2的JSONField ORM查询对嵌套数组的支持在MariaDB下存在局限性:默认的双下划线链式查询(如product_settings__resources__resource_config__...)无法自动遍历数组元素(需要明确指定数组通配符[*]),而MariaDB的JSON函数语法与PostgreSQL的jsonb操作不同,导致原查询无法匹配到目标数据。
可行解决方案
方案1:使用RawSQL直接执行MariaDB原生JSON查询
直接通过原生SQL调用MariaDB的JSON_SEARCH函数,精准定位嵌套数组中的目标值:
from django.db.models import RawSQL # 替换yourapp_product为你的实际表名(app名+模型名小写) products = Product.objects.raw(''' SELECT * FROM yourapp_product WHERE JSON_SEARCH(product_settings, 'one', 'building', NULL, '$.resources[*].resource_config.linked_to.params.deposit.type') IS NOT NULL ''')
JSON_SEARCH参数说明:- 第一个参数:要查询的JSON字段
'one':找到第一个匹配项即停止'building':要匹配的目标值NULL:不限制路径前缀- 最后一个参数:完整的JSON路径,
[*]表示遍历数组中的所有元素
方案2:使用Django Func表达式封装MariaDB JSON函数
通过Django的Func类封装JSON_CONTAINS函数,实现ORM风格的查询:
from django.db.models import Func, Value, BooleanField class JSONContains(Func): function = 'JSON_CONTAINS' output_field = BooleanField() template = "%(function)s(%(field)s, %(value)s, %(path)s)" products = Product.objects.filter( JSONContains( field='product_settings', value=Value('{"type": "building"}'), path=Value('$.resources[*].resource_config.linked_to.params.deposit') ) )
- 此方法通过自定义
Func类适配MariaDB的JSON_CONTAINS语法,检查指定路径下的JSON对象是否包含目标键值对。
注意事项
- 确保你的MariaDB版本≥10.2,该版本开始完整支持JSON函数。
- 若嵌套数组层级或结构有变动,需同步调整JSON路径中的
[*]和节点名称。
内容的提问来源于stack exchange,提问作者Samuel Dauzon
相关产品推荐
相关产品推荐

