Sie können jsonb_extract_path_text verwenden über eine Funktion object als Alternative zum Feld transform:
Pet.annotate(dinner=Func(
F('data'), Value('diet'), Value('dinner'),
function='jsonb_extract_path_text')) \
.values('dinner') \
.annotate(total=Count('dinner'))
Der Grund, warum das Feld data__diet__dinner
transformiert fehlschlägt ist ein Fehler in Django, wenn Sie tiefer als nur eine Ebene in die json-Struktur and einsteigen Verwenden Sie GROUP BY
im SQL. Die erste Ebene (name
, animal
, diet
) sollte gut funktionieren.
Der Grund scheint zu sein, dass Django für verschachtelte Transformationen die verwendete SQL-Syntax ändert und von einem einzelnen Wert zu einer Liste wechselt, um den Pfad in die JSON-Struktur anzugeben.
Dies ist die Syntax, die für nicht verschachtelte json-Transformationen (=erste Ebene) verwendet wird:
"appname_pet"."data" -> 'diet'
Und dies ist die Syntax, die für verschachtelte Transformationen verwendet wird (tiefer als die erste Ebene):
"appname_pet"."data" #> ARRAY['diet', 'dinner']
Beim Erstellen der Abfrage verschluckt sich Django an dieser Liste, während es das erforderliche GROUP BY
ausarbeitet Klauseln. Dies scheint keine unvermeidliche Einschränkung zu sein; Die Unterstützung für Transformationen ist ziemlich neu, und dies ist möglicherweise einer der Knicke, die noch nicht ausgearbeitet wurden. Wenn Sie also ein Django-Ticket
öffnen , dies könnte in einigen Versionen später funktionieren.