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

如何用Django QuerySet实现指定SQL查询?QuerySet比原生SQL快吗?

问题解答

1. 如何用Django QuerySet实现指定SQL查询

你的原生SQL是从s2_user_subscription左连s2_bot_categories_mappings,取出用户ID、机器人ID和对应的分类ID。基于给定的模型,可通过以下方式实现:

方式一:匹配原生SQL逻辑(直接生成左连接)

利用Django ORM的双下划线关联语法自动生成左连接,同时通过F()表达式保证输出字段名与原生SQL一致:

from django.db.models import F

queryset = S2UserSubscription.objects.values(
    id_s2_users=F('id_s2_users'),
    id_s2_bot=F('id_s2_bot'),
    id_s2_bot_categories=F('id_s2_bot__s2botcategoriesmappings__id_s2_bot_categories')
)

说明:id_s2_bot__s2botcategoriesmappings是反向关联的默认名称(因S2BotCategoriesMappings的id_s2_bot字段未指定related_name)。如果之前给该外键设置了related_name(比如related_name='category_mappings'),需改为id_s2_bot__category_mappings__id_s2_bot_categories。

方式二:聚合一对多结果(可选)

如果一个机器人对应多个分类映射,上述QuerySet会返回多行匹配结果(和原生SQL行为一致)。若要将每个订阅的所有分类ID聚合为一个数组(需PostgreSQL支持),可使用:

from django.contrib.postgres.aggregates import ArrayAgg

queryset = S2UserSubscription.objects.annotate(
    category_ids=ArrayAgg('id_s2_bot__s2botcategoriesmappings__id_s2_bot_categories', default=[])
).values('id_s2_users', 'id_s2_bot', 'category_ids')

2. Django QuerySet是否比原生SQL关联查询更快?

答案是不一定,核心逻辑如下:

  • QuerySet本质是将Python代码转换为SQL执行,最终性能取决于生成的SQL质量。如果QuerySet生成的SQL和你手写的原生SQL完全一致,两者性能无差异。
  • 若QuerySet生成了冗余SQL(比如不必要的字段查询、多余表连接),或未正确利用索引,此时手写优化后的原生SQL会更快。
  • 反之,若你对SQL优化不熟悉,Django ORM通常会生成规范的高效SQL,避免低级错误(如SQL注入),同时提升代码可维护性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 12:25:25