фильтровать свойство внешнего ключа в django-nonrel

Каков наилучший способ фильтрации на основе свойства внешнего ключа в нереляционной базе данных? Я понимаю, что отсутствие поддержки 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)

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


person munchybunch    schedule 27.12.2010    source источник


Ответы (2)


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

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

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

person Waldemar Kornewald    schedule 27.12.2010
comment
Является ли январская часть ссылкой на базы данных sql в GAE? Потому что они всегда ссылаются на конец года, а год, кажется, никогда не кончается. :П - person munchybunch; 28.12.2010
comment
Ух ты, ты разработчик django-nonrel!? Это потрясающе, спасибо за всю вашу работу. С нетерпением жду января... - person munchybunch; 28.12.2010

Январь прошел, и теперь 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(),})
person Pedro Andrade    schedule 07.06.2011