2017-07-18 3 views
1

Ich benutze Django's Postgres ArrayField.Django - Abfrage neuesten Datums in einem ArrayField

sagen, dass ich ein Modell wie diese:

from django.db import models 
from django.contrib.postgres.fields import ArrayField 

class Event(models.Model): 
    name = models.CharField(max_length=200) 
    dates = ArrayField(models.DateField()) 

Und ich will die Event mit dem jeweils neuesten Termine finden. Gibt es eine Möglichkeit, ein Abfrage-Set zu erstellen, das das tun kann?

+1

Wäre es nicht besser, eine Ersatztabelle mit 'EventDates' zu haben? – joanolo

+0

Möglicherweise, aber zur Zeit ist die DB so wie es ist und hat eine Tonne Daten drin. Ich hoffe, herauszufinden, ob es mit einem ArrayField getan werden kann, bevor ich eine wichtige Schemaänderung und Datenmigration mache. Außerdem ist diese spezielle Tabelle ziemlich hart und muss für die meisten datumsbezogenen Abfragen schnell sein (anders als diese bestimmte Max-Datum-Abfrage - die nicht benötigt wird, um schnell zu sein, da sie nicht so oft benötigt wird). also möchte ich Joins vermeiden. – Troy

Antwort

1

Ich kann nicht in die Details von Django kommen (ich bin nicht so viel darin). Doch einige Hinweise:

  1. Verwendung direkt die SQL-Sprache, verwenden Sie:

    SELECT 
        name, (SELECT max(d) FROM unnest(dates) d) AS latest_date 
    FROM 
        Event ; 
    
  2. Um backconvert dies zu Django, überprüfen Django Postgresql ArrayField aggregation, und passen Sie es Ihren specifc Fall.

    Ich denke, etwas entlang der Linien des folgenden Codes sollte den Trick tun:

    Event.objects.annotate(arr_els=Func(F('dates'), function='unnest')) \ 
         .values_list('arr_els', flat=True).aggregate(Max('arr_els')) 
    

Siehe SQL Beispiel bei dbfiddle here.

1) Ich habe nicht die richtige Umgebung, um den Django-Teil zu testen ... also ist dies nicht getestet.

+0

Hast du den Code wirklich probiert? Musstest du es ändern? – joanolo

+1

Ja, tat ich. Das obige findet tatsächlich das späteste Datum unter den "Ereignissen" statt dem "Ereignis" mit dem spätesten Datum. Aber das war es, was ich letztendlich versuchte zu bekommen. Und wenn ich das 'Event' möchte, ist es einfach, es abzufragen, sobald ich das Datum habe. – Troy

Verwandte Themen