【问题标题】:Using Key in NDB to retrieve an entity在 NDB 中使用 Key 来检索实体
【发布时间】:2013-05-25 22:44:33
【问题描述】:

我有这样的结构:有章节 (ancestor=Book) 的书有页面 (ancestor=Chapter)

我很清楚,要按 ID 搜索章节,我需要按祖先查询搜索书。而且我今天了解到,如果我有所有的键,我可以直接检索实体,而无需先获取书,然后是章节,然后是页面,这样:

page_key = ndb.Key('Book', long(bookId), 'Chapter', long(chapterId), 'Page', long(pageId))
page = page_key.get()

我的疑问是:要通过例如页码获取页面,我必须先获取章节吗?

例如:

class Book(ndb.Model):
    name = ndb.StringProperty(required=True)

    # Search by id
    @classmethod
    def by_id(cls, id):
        return Book.get_by_id(long(id))

class Chapter(ndb.Model):
    name = ndb.StringProperty(required=True)

    # Search by id
    @classmethod
    def by_id(cls, id, book):
        return Chapter.get_by_id(long(id), parent=book.key)

class Page(ndb.Model):
    pageNumber = ndb.IntegerProperty(default=1)
    content = ndb.StringProperty(required=True)

    # Search by page
    @classmethod
    def by_page(cls, number, chapter):
        page = Page.query(ancestor=chapter.key)
        page = page.filter(Page.pageNumber == int(number))
        return page.get()

实际上,当我需要搜索页面以显示其内容时,我正在这样做:

getPage?bookId=5901353784180736&chapterId=5655612935372800&page=2

所以,在控制器中,我做了这个:

def get(self):
    # Get the id parameters
    bookId = self.request.get('bookId')
    chapterId = self.request.get('chapterId')
    pageNumber = self.request.get('page')

    if bookId and chapterId and pageNumber:
        # Must be a digit
        if bookId.isdigit() and chapterId.isdigit() and pageNumber.isdigit():
            # Get the chapter
            chapter_key = ndb.Key('Book', long(bookId), 'Chapter', long(chapterId))
            chapter = chapter_key.get()

            if chapter:
                # Get the page
                page = Page.by_number(pageNumber, chapter)

这是正确的方法还是我错过了更好的方法,我只能访问数据存储区,而不是两个?

如果这是对的,我想这种使用 NDB 的工作方式对数据存储没有任何影响,因为重复调用此页面总是会命中同一章节和页面的 NDB 缓存(因为我是使用 get() 方法,它不是 fetch() 命令)。我猜对了吗?

【问题讨论】:

  • 你怎么又问这个问题了?
  • 不一样的@DanielRoseman。在上一个问题中,您解决了读取 3 次有键的问题。现在这个问题是要知道是否有其他方法可以让实体不知道密钥。对不起,如果我让你感到困惑。
  • 谢谢,很公平。

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


【解决方案1】:

您可以通过执行祖先查询而不是获取来一次性完成:

chapter_key = ndb.Key('Book', long(bookId), 'Chapter', long(chapterId))
page = Page.query(Page.pageNumber==pageNumber, ancestor=chapter_key)

【讨论】:

  • 伟大的人!!,它工作得很好。我对祖先的钥匙有点误解,但我想现在我理解得更好了。在我的 by_page 方法中,我传递了章节实体,但通过 ancestor=chapter.key 进行搜索,这很愚蠢,因为我只需要密钥。我将更改我的所有代码以在我只需要键的部分中仅使用键而不是完整实体,这将为我节省大量数据库命中。
  • 关于最后一个问题,我说的对吗?即使调用 3 个不同的实体,因为我使用的是 get(),NDB 正在从缓存中获取它们,从而最大限度地减少对数据库的访问?
  • 在一定程度上是的,但是你不能保证东西真的在缓存中,所以尽可能减少对数据存储的访问总是更好的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-04-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-27
  • 2015-03-03
  • 2020-03-29
相关资源
最近更新 更多