Фильтр на имущество Foreign Key в Django-Nonrel
-
13-10-2019 - |
Вопрос
Какова лучшая практика для фильтрации, основанной на собственности иностранного ключа в нереляционной базе данных? Я понимаю, что отсутствие join
Поддержка делает вещи более сложными, и поэтому мне было интересно, как другие обошли это.
В моем случае у меня есть события, которые принадлежат сайтам, которые принадлежат регионам. Я хочу отфильтровать все события в данном регионе. Атмосфера Event
имеет site
собственность, которая является иностранным ключом к Site
, который, в свою очередь region
иностранный ключ к Region
:
region = Region.objects.get(id=regionID)
events = Event.objects.filter(site__region=region)
Это не работает, потому что сайт __region требует join
И это не поддерживается на Django-Nonrel, работающем в Google App Engine. (Я получил Caught DatabaseError while rendering: This query is not supported by the database.
в качестве ошибки.) Таким образом, я итерация через события, добавляя те, которые соответствуют списку:
events = list()
region = Region.objects.get(id=regionID)
for event in Event.object.all():
if event.site.region==region:
events.append(event)
Это хороший способ делать что -то? Есть ли что -то глупое, что я упустил из виду? Заранее спасибо!
Решение
Это очень неэффективное решение, потому что вы сайт и регион Dereference, вызывая много -много запросов. Это не будет масштабироваться, возможно, на 100 событий в вашем БД.
Лучшее решение - денормализовать ваши данные путем копирования, например, идентификатора региона в событие на save (). Тогда вы можете напрямую выполнять event.objects.filter (region_id = regionid). Полученный код становится менее чистым и поддерживаемым, но именно так все работает на нереляционном DBS, Cегодня.
Все, что я могу сказать сейчас, это: подождите до конца января, если сможете. ;)
Другие советы
Январь ушел, и Dbindexer теперь поддерживает простые соединения. Вы можете прочитать здесь: http://www.allbuttonspressed.com/blog/django/joins-for-nosql-databases-via-django-dbindexer-first-steps
Если вы уже используете dbindexer, вы должны просто зарегистрировать свой индекс, используя что -то подобное:
# photo/dbindexes.py:
from models import Event
from dbindexer.lookups import StandardLookup
from dbindexer.api import register_index
register_index(Event, {'site__region': StandardLookup(),})