Using Key in NDB to retrieve an entity

梦想的初衷 提交于 2019-12-02 08:25:33

问题


I have this structure: Books that have Chapters (ancestor=Book) that have Pages (ancestor=Chapter)

It is clear for me that, to search for a Chapter by ID, I need the book to search by ancestor query. And I've learn today that if I have all the keys, I can retrieve directly the entity without need of get first the book, then the chapter and then the page, in this way:

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

My doubt is: to get the page by, for example, page number, must I get first the chapter?

For example :

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()

Actually, when I need to search the Page to display its contents, I'm doing this:

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

So, in the controller, I make this:

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)

Is this the right way or there is a better way I'm missing where I can do only an access to datastore, instead two?

If this is right, I suppose that this way of work, using NDB, does not have any impact on the datastore, because repeated calls to this page always hit the NDB cache for the same chapter and page (because I'm using get() method, it is not a fetch() command). Is my suppose right?


回答1:


You can do this in one go by doing an ancestor query, rather than a get:

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


来源:https://stackoverflow.com/questions/16834797/using-key-in-ndb-to-retrieve-an-entity

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!