Учусь работать в GAE. Я прочитал много статей, все документы NDB от Google и некоторые вопросы здесь. Я так привык к SQL, но преобразовать мое мышление за последние 20 лет в NoSQL было немного сложно для меня, и все эти различные решения, приведенные здесь, сводят меня с ума.
У меня следующая простая структура: КНИГИ, в которых могут быть ГЛАВЫ, ГЛАВЫ, которые могут иметь ГОЛОСА. Например, в книге «Страж» может быть 3 главы, и каждая глава будет иметь 0, 8 и 12 голосов.
В традиционном SQL я просто делаю внешние ключи от ГОЛОСОВ к ГЛАВАМ и КНИГАМ и от ГЛАВ к КНИГАМ.
Я делаю это для своих моделей:
class Book(ndb.Model):
title = ndb.StringProperty(required=True)
author = ndb.StringProperty(required=True)
created = ndb.DateTimeProperty(auto_now_add=True)
# Define a default ancestor for all the books
@staticmethod
def bookKey(group='books'):
return ndb.Key(Book, group)
# Search all
@classmethod
def getAll(cls):
q = Book.query(ancestor=cls.bookKey())
q = q.order(Book.title)
books = q.fetch(100)
return books
@classmethod
def byId(cls, id):
book = Book.get_by_id(long(id), cls.bookKey())
# Get all the Chapters for a book
def getChapters(self):
chapters = Chapter.query(ancestor=self).order(Chapter.number).fetch(100)
return chapters
class Chapter(ndb.Model):
""" All chapters that a book have """
title = ndb.StringProperty(required=True)
number = ndb.IntegerProperty(default=1)
created = ndb.DateTimeProperty(auto_now_add=True)
book = ndb.KeyProperty(kind=Book)
# Search by Book (parent)
@classmethod
def byBook(cls, book, limit=100):
chapter = book.getChapters()
return chapter
# Search by id
@classmethod
def byId(cls, id, book):
return Chapter.get_by_id(long(id), parent=book)
class Vote(ndb.Model):
""" All votes that a book-chapter have """
value = ndb.IntegerProperty(default=1)
book = ndb.KeyProperty(kind=Book)
chapter = ndb.KeyProperty(kind=Chapter)
Что ж, мои сомнения:
- Это правильный подход?
- Созданная мною функция bookKey () хороша для наличия «фиктивного предка», чтобы гарантировать, что все сущности используют предков?
- Должен ли я определить в классе Vote ссылку на книгу и на главу, поскольку это были внешние ключи (как я думаю, я сделал)?
- Хорошо ли определен способ извлечения глав из книги? Я имею в виду, что в классе Chapter функция byBook использует функцию из класса Book. Или я должен избегать использования функций из другой сущности, чтобы иметь более чистый код?
- как я могу получить все голоса за главу?
- Каковы верные способы получить сумму всех голосов за конкретную главу и за конкретную книгу?
Наконец, я покажу единую таблицу со всеми моими книгами. В таблице я хочу указать сумму всех голосов за каждую книгу. Например:
Имя | Голосует Sentinel | 30 голосов Ведьма | 4 голоса
Как я могу получить эту информацию, особенно подсчитанные голоса.
Затем, щелкнув название книги, я хочу показать все его главы (я полагаю, именно тогда я должен использовать функцию byBook в модели Chapter, верно?).
Какой GQL мне нужен для получения таких данных?
Заранее спасибо.