PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Django annote le nombre dans JSONField avec Postgres

Vous pouvez utiliser jsonb_extract_path_text via une Func objet comme alternative à la transformation de champ :

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

La raison pour laquelle le champ transforme data__diet__dinner échoue est une erreur dans Django lorsque vous allez plus loin qu'un seul niveau dans la structure json et utilisez GROUP BY dans le SQL. Le premier niveau (name , animal , diet ) devrait fonctionner correctement.

La raison semble être que pour les transformations imbriquées, Django modifie la syntaxe SQL utilisée, passant d'une valeur unique à une liste pour spécifier le chemin dans la structure json.

Voici la syntaxe utilisée pour les transformations json non imbriquées (=premier niveau) :

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

Et voici la syntaxe utilisée pour les transformations imbriquées (plus profondes que le premier niveau) :

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

Lors de la construction de la requête, Django s'étouffe sur cette liste tout en travaillant sur le GROUP BY requis clauses. Cela ne semble pas être une restriction inévitable; la prise en charge des transformations est assez nouvelle, et c'est peut-être l'un des problèmes qui n'ont pas encore été résolus. Donc si vous ouvrez un ticket Django , cela pourrait ne fonctionner que quelques versions plus tard.