фильтр по свойству внешнего ключа в django-nonrel - PullRequest
3 голосов
/ 27 декабря 2010

Какова лучшая практика для фильтрации на основе свойства внешнего ключа в нереляционной базе данных?Я понимаю, что отсутствие поддержки join усложняет ситуацию, и поэтому мне было интересно, как другие обошли это.

В моем случае у меня есть события, которые принадлежат сайтам, которые принадлежат регионам.Я хочу отфильтровать все события в данном регионе.Event имеет свойство site, которое является внешним ключом для Site, которое, в свою очередь, имеет region внешний ключ для Region:

region = Region.objects.get(id=regionID)
events = Event.objects.filter(site__region=region)

Это неработать, потому что site__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)

Это хороший способ делать что-то?Есть что-то глупое, что я упустил из виду?Заранее спасибо!

Ответы [ 2 ]

8 голосов
/ 28 декабря 2010

Это очень неэффективное решение, потому что вы разыменовываете сайт и регион, вызывая множество запросов.Это не будет превышать, возможно, 100 событий в вашей БД.

Лучшее решение состоит в денормализации ваших данных путем копирования, например, идентификатора региона в Event при сохранении ().Затем вы можете напрямую выполнить Event.objects.filter (region_id = regionID).Получающийся код становится менее чистым и обслуживаемым, но именно так все и работает на нереляционных БД, сегодня .

Все, что я могу сейчас сказать, это: ждать до конца января, есливы можете.;)

1 голос
/ 08 июня 2011

Январь прошел, и dbindexer теперь поддерживает простые JOINS. Вы можете прочитать о здесь: 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(),})
...