Filter für ausländisches Schlüssel Eigentum in Django-nonrel
-
13-10-2019 - |
Frage
Was ist die beste Praxis für die Filterung auf der Grundlage der Eigenschaft eines ausländischen Schlüssels in einer nicht-relationalen Datenbank? Ich verstehe, dass der Mangel an join
Die Unterstützung macht die Dinge komplizierter, und so fragte ich mich, wie andere es ums Leben gekommen sind.
In meinem Fall habe ich Ereignisse, die zu Websites gehören, die zu Regionen gehören. Ich möchte alle Ereignisse in einer bestimmten Region filtern. Ein Event
hat ein site
Eigentum, das ein fremder Schlüssel zu a ist Site
, was wiederum eine hat region
Fremdschlüssel zu a Region
:
region = Region.objects.get(id=regionID)
events = Event.objects.filter(site__region=region)
Dies funktioniert nicht, da Site__region a erfordert join
Und das wird nicht bei Django-Nonrel unterstützt, das auf Google App Engine ausgeführt wird. (Ich bekomme Caught DatabaseError while rendering: This query is not supported by the database.
Als Fehler.) Ich habe also Ereignisse durchlaufen und diejenigen hinzugefügt, die zu einer Liste übereinstimmen:
events = list()
region = Region.objects.get(id=regionID)
for event in Event.object.all():
if event.site.region==region:
events.append(event)
Ist das ein guter Weg, um Dinge zu tun? Gibt es etwas Dummes, das ich übersehen habe? Danke im Voraus!
Lösung
Das ist eine sehr ineffiziente Lösung, da Sie Dereference -Site und Region und viele Fragen verursachen. Dies wird nicht über 100 Ereignisse in Ihrer DB hinaus skalieren.
Die beste Lösung besteht darin, Ihre Daten zu denormalisieren, indem Sie zB der ID der Region in Ereignis auf Save () kopieren. Dann können Sie Event.Objects.Filter (Region_id = RegionID) direkt ausführen. Der resultierende Code wird weniger sauber und wartbar, aber so funktioniert die Dinge auf nicht-relationalen DBs. heute.
Ich kann jetzt nur noch sagen: Warten Sie bis Ende Januar, wenn Sie können. ;))
Andere Tipps
Der Januar ist gegangen und Dbindexer unterstützt jetzt einfache Angerinnen. Sie können hier darüber lesen: http://www.allbuttonspressed.com/blog/django/joins-for-nosql-databases-via-django-dbindexer-first-teps
Wenn Sie DBIndexer bereits verwenden, sollten Sie Ihren Index einfach mit so etwas registrieren:
# photo/dbindexes.py:
from models import Event
from dbindexer.lookups import StandardLookup
from dbindexer.api import register_index
register_index(Event, {'site__region': StandardLookup(),})