通过jsonb字段执行Django连接和分组

时间:2018-09-01 19:01:52

标签: django django-orm jsonb

我遍历了所有有关注释,聚合的Django资料, 无法理解如何使用Django ORM实施以下查询。

此示例并非来自生产,而是具有教育意义,因此可能与最佳实践不同。

我需要查询,该查询将输出Colors表中每种每种颜色的房屋数量:

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表没有用于颜色的ForeignKey,而是具有带有json参数的colorid

1 个答案:

答案 0 :(得分:0)

请注意,建立模型的方式实际上不需要联接(即使在SQL中也是如此)。同样从ORM的角度来看,这是拥有与显式不相关(即与ForeignKey相关)的伪相关模型的一种非常奇怪的方法。就是说,您的查询集中缺少的链接是KeyTextTransform,(目前)该文档的文档不多,但是可以找到here

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')
)