通过jsonb字段执行Django连接和分组
我已经浏览了所有Django源代码,关于注释、聚合等 无法理解如何使用Django ORM实现以下查询 这个例子不是来自生产,而是教育性的,因此它可能不同于最佳实践 我需要一个查询,该查询将输出颜色表中存在的每种颜色的房屋数量:通过jsonb字段执行Django连接和分组,django,django-orm,jsonb,Django,Django Orm,Jsonb,我已经浏览了所有Django源代码,关于注释、聚合等 无法理解如何使用Django ORM实现以下查询 这个例子不是来自生产,而是教育性的,因此它可能不同于最佳实践 我需要一个查询,该查询将输出颜色表中存在的每种颜色的房屋数量: select clr.id as colorId, count(*) as count from colors as clr inner join houses as c on clr.id = cast(c.parameters ->> 'col
select
clr.id as colorId, count(*) as count
from colors as clr
inner join houses as c
on clr.id = cast(c.parameters ->> 'colorId' as int)
group by colorId;
数据模式定义如下:
CREATE TABLE colors (
id serial primary key NOT NULL,
name text NOT NULL
);
CREATE TABLE houses (
id serial primary key NOT NULL,
parameters jsonb NOT NULL
);
insert into colors (id, name) values
(1, 'red'),
(2, 'green'),
(3, 'blue'),
(4, 'other');
insert into houses (parameters) values
('{"price": 1000, "colorId": 1}'),
('{"price": 2000, "colorId": 2}'),
('{"price": 2500, "colorId": 2}'),
('{"price": 3000, "colorId": 3}'),
('{"price": 3100, "colorId": 3}'),
('{"price": 3200, "colorId": 3}');
Django ORM的实现是什么?
简单的查询非常简单,但我没有理解jsonb字段上的聚合和注释
模型如下:
from django.contrib.postgres.fields import JSONField, TextField
from django.db import models
class Color(models.Model):
name = models.TextField()
class House(models.Model):
parameters = models.JSONField()
该查询应类似于:
from django.db.models import Count
Houses.objects.values('color').annotate(dcount=Count('color'))
但是Houses表没有指向Colors的ForeignKey,相反,它有带有json参数的colorid。请注意,在设置模型的方式中,实际上并不需要连接(即使在SQL中)。同样从ORM的角度来看,这是一种非常奇怪的方式,可以使用不显式相关的伪相关模型(即,使用ForeignKey)。也就是说,queryset中缺少的链接是KeyTextTransform,它(目前)没有很好的文档记录,但可以找到:
请注意,在设置模型的方式中,实际上并不需要连接(即使在SQL中)。同样从ORM的角度来看,这是一种非常奇怪的方式,可以使用不显式相关的伪相关模型(即,使用ForeignKey)。也就是说,queryset中缺少的链接是KeyTextTransform,它(目前)没有很好的文档记录,但可以找到:
您好,Dmitry-可以在您的
models.py
文件中查看房屋和颜色表吗…@MichealJRoberts嗨,Micheal,我已经添加了模型Hi-Dmitry-可以在您的models.py
文件中查看房屋和颜色表吗…@MichealJRoberts嗨,Micheal,我已经添加了模型谢谢,这非常接近了,我忘了提到我只需要根据颜色表中存在的颜色进行分组。所以内部连接实际上是必要的,我同意你们的观点,非常奇怪的伪关系模型,这不是生产,只是教育,这可能吗?dcount=Count('color\u id',filter=Q(color\u id\u in=Subquery(color.values('id')))如果我最后的评论是正确的,我会接受你的回答谢谢,这非常接近,我忘了提到我只需要根据颜色表中存在的颜色进行分组。所以内部连接实际上是必要的,我同意你们的观点,非常奇怪的伪关系模型,这不是生产,只是教育,这可能吗?dcount=Count('color\u id',filter=Q(color\u id\u in=Subquery(color.values('id')))如果我最后的评论是正确的,我将接受你的答案
from django.contrib.postgres.fields.jsonb import KeyTextTransform
from django.db.models import Count
Houses.objects.annotate(
color_id=KeyTextTransform('colorId', 'parameters')
).values(
'color_id'
).annotate(
dcount=Count('color_id')
)