문제

What's the best practice for filtering based on a foreign key's property in a non-relational database? I understand that the lack of join support makes things more complicated, and so I was wondering how others got around it.

In my case, I have events, which belong to sites, which belong to regions. I want to filter all events in a given region. An Event has a site property that is a foreign key to a Site, which in turn has a region foreign key to a Region:

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

This doesn't work, because site__region requires a join and that's not supported on django-nonrel running on Google App Engine. (I get Caught DatabaseError while rendering: This query is not supported by the database. as an error.) I've thus been iterating through events, adding those that match to a list:

events = list()
region = Region.objects.get(id=regionID)
for event in Event.object.all():
    if event.site.region==region:
        events.append(event)

Is this a good way to be doing things? Is there something silly that I've overlooked? Thanks in advance!

도움이 되었습니까?

해결책

That's a very inefficient solution because you dereference site and region, causing lots and lots of queries. This will not scale beyond maybe 100 events in your DB.

The best solution is to denormalize your data by copying e.g. the region's id into Event on save(). Then you can directly do Event.objects.filter(region_id=regionID). The resulting code becomes less clean and maintainable, but that's the way things work on non-relational DBs, today.

All I can say right now is: Wait until the end of January if you can. ;)

다른 팁

January has gone and dbindexer now supports simple JOINS. You can read about here: http://www.allbuttonspressed.com/blog/django/joins-for-nosql-databases-via-django-dbindexer-first-steps

If you are already using dbindexer you should simply register your index using something like this:

# photo/dbindexes.py:

from models import Event
from dbindexer.lookups import StandardLookup
from dbindexer.api import register_index

register_index(Event, {'site__region': StandardLookup(),})
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top