2014-06-24 8 views
8

Próba modelowania relacji wielu do wielu za pomocą ndb. Czy ktokolwiek może wskazać dobry przykład, jak to zrobić?Relacja wielu do wielu w ndb

Pod tutaj jest przykładem tego, co mam w tej chwili:

class Person(ndb.Model): 
    guilds = ndb.KeyProperty(kind="Guild", repeated=True) 

class Guild(ndb.Model) 
    members = ndb.KeyProperty(kind="Person", repeated=True) 

    def add_person(self, person): 
     self.members.append(person.key) 
     self.put() 
     person.guilds.append(self.key) 
     person.put() 

Czy to jest prawidłowy sposób się do tego zabrać? Dobrze się rozejrzałam, ale nie mogę znaleźć żadnej dobrej dokumentacji na ten temat.

W przeglądarce datastore widzę, że relacja ta jest zapisana jako lista kluczy, której oczekuję.

Jednak, gdy staram się je wykorzystywać w metodach klasy osoba taka jak ta:

for guild in self.guilds: 

uzyskać:

TypeError: 'KeyProperty' object is not iterable 
+0

'dla gildii w self.guilds' powinno działać. Sprawdź againt jeśli umieścisz 'repeat = True' w Person:' guilds = ndb.KeyProperty (kind = "Guild", repeat = True) ' –

+0

Uwaga: istnieje górny limit liczby relacji, które można osiągnąć przy powtarzających się właściwościach . Jeśli potrzebujesz wielu tysięcy lub więcej, wielu do wielu relacji lub musisz nazywać Cię relacjami, wtedy pośrednia jednostka, która ma dwie cechy szczególne, wskazując na każdy koniec związku, również będzie działała, ale generalnie jest mniej wydajna i możesz mieć do przechowywania niektórych niepotrzebnych informacji w tym obiekcie, jeśli potrzebujesz widoków podsumowania, aby uniknąć dodatkowych filtrów podglądu. –

Odpowiedz

12

Nie, to nie jest właściwa droga do tego zabrać.

można modelować wiele-do-wielu relacji z tylko jednym wielokrotnym miejscu:

class Person(ndb.Model): 
    guilds = ndb.KeyProperty(kind="Guild", repeated=True) 

class Guild(ndb.Model): 
    @property 
    def members(self): 
     return Person.query().filter(Person.guilds == self.key) 

    def add_person(self, person): 
     person.guilds.append(self.key) 
     person.put() 

lub na odwrót z:

class Person(ndb.Model): 
    @property 
    def guilds(self): 
     return Guild.query().filter(Guild.members == self.key) 

class Guild(ndb.Model): 
    members = ndb.KeyProperty(kind="Person", repeated=True) 

    def add_person(self, person): 
     self.members.append(person.key) 
     self.put() 

Kierunek relacji zależy od wielu czynników (firmy model, liczba gildii na osobę, liczba członków na gildię, itp.)

+0

To zadziałało wielkie dzięki. Nadal nie jestem pewien, dlaczego otrzymuję: 'TypeError: 'Obiekt KeyProperty' nie jest iterable' o tym samym typie właściwości. To działa dla mnie, ale myślę, że górny limit powtórzonej KeyProperty to 5000, więc może nie być tak dobry dla ludzi z większą liczbą podmiotów. – chrisw

+0

Nie ma za co. Jeśli masz wiele jednostek po każdej stronie relacji, powinieneś utworzyć kolejną jednostkę dla relacji, w ten sam sposób, w jaki tworzysz nową tabelę w relacyjnej bazie danych dla relacji wiele do wielu. Ale pamiętaj, że nie możesz tworzyć złączeń w zapytaniach dotyczących magazynów danych. –

+0

Tego należy unikać. Odwołaj się do tego http://stackoverflow.com/questions/15377119/gae-ndb-design-performance-and-use-of-repeated-properties/15418435#15418435 – EsseTi

Powiązane problemy