GAE:从RDBMS到NDB问题

时间:2013-05-21 14:20:19

标签: python google-app-engine app-engine-ndb

我正在学习GAE工作。我已经阅读了很多论文,所有来自谷歌的NDB文档和asome问题都在这里。我已经习惯了SQL,但是将我过去20年的思维方式转变为NoSQL对我来说有点困难,所有这些不同的解决方案都让我疯狂。

我有下一个简单的结构: 书本比可以有章节 可以有投票的章节 例如,Book“Sentinel”可以有3章,每章将分别有0,8和12票。

在传统的SQL中,我只需要将外键从VOTES到CHAPTERS和BOOKS,从CHAPTERS到BOOKS。

我为我的模特做了这个:

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)

好吧,我的怀疑是:

  1. 这种做法是否正确?
  2. 我创建的函数bookKey()有一个“Dummy Ancestor”以确保所有实体都使用祖先吗?
  3. 我必须在投票类中定义书籍和章节的参考,因为它是外键(就像我想的那样)?
  4. 是否明确了从书中检索章节的方法?我的意思是,在Chapter类中,函数byBook使用Book类中的函数。或者我必须避免使用其他实体的函数来获得更干净的代码吗?
  5. 如何检索章节的所有投票?
  6. 哪种方法可以获得特定章节和特定书籍的所有选票总和?
  7. 最后,我将展示包含所有书籍的单个表格。在表格中,我希望得到每本书的所有选票总和。例如:

    姓名|投票 Sentinel | 30票 巫婆| 4票

    我如何获得这些信息,特别是计票数。

    然后,点击书名,我想展示他的所有章节(当我必须在章节模型上使用byBook函数时,我会说这是对的吗?)。

    我需要获取此类数据的GQL是什么?

    提前致谢。

1 个答案:

答案 0 :(得分:2)

良好的开端。 GAE的数据存储有点令人困惑。因为它是无模式的,所以我发现处理实体更像是处理内存中的对象/数据结构而不是处理数据库表。

以下是我要做的一些不同的事情:

  • 您似乎在一个祖先下创建了所有书籍。可怕的主意。在性能方面让你失望。除非您需要对当前代码中没有的一组书籍进行某些交易操作,否则这是不对的。

  • 从Book.getChapters()函数看,你想让一本书成为一堆章节的祖先。这可能是祖先的一个很好的用途。我没有看到您创建章节的代码,但请确保将相应的书指定为祖先。

  • 我只是在一本书或一章中包含投票作为属性。没有必要将它作为一个单独的类型,您需要发出额外的查询。

  • 如果每本书的章节数量有限,我会考虑在章节中使用StructuredProperty。 StructuredProperties本质上是父实体(Book)中的结构化数据。您将受到Book实体的最大大小(1MB)的限制,但如果它适合,它将为您节省额外查询的成本,因为如果没有相应的书籍,您将不会查询章节。< / p>