sql >> Base de Datos >  >> RDS >> PostgreSQL

Django anota el recuento en JSONField con Postgres

Puede usar jsonb_extract_path_text a través de un Func objeto como alternativa a la transformación de campo:

Pet.annotate(dinner=Func(
    F('data'), Value('diet'), Value('dinner'),
    function='jsonb_extract_path_text'))  \
.values('dinner')  \
.annotate(total=Count('dinner'))

La razón por la que el campo transforma data__diet__dinner falla es un error dentro de Django cuando profundizas más de un nivel en la estructura json y usa GROUP BY en el SQL. El primer nivel (name , animal , diet ) debería funcionar bien.

La razón parece ser que para las transformaciones anidadas, Django cambia la sintaxis SQL utilizada, cambiando de un solo valor a una lista para especificar la ruta a la estructura json.

Esta es la sintaxis utilizada para las transformaciones json no anidadas (=primer nivel):

"appname_pet"."data" -> 'diet'

Y esta es la sintaxis utilizada para las transformaciones anidadas (más profundas que el primer nivel):

"appname_pet"."data" #> ARRAY['diet', 'dinner']

Mientras construye la consulta, Django se atraganta con esa lista mientras resuelve el GROUP BY requerido. cláusulas. Esto no parece ser una restricción inevitable; el soporte para transformaciones es bastante nuevo, y este es posiblemente uno de los problemas que aún no se han resuelto. Entonces, si abre un ticket de Django , esto podría funcionar en algunas versiones más adelante.