Does GAE Datastore support eager fetching?

三世轮回 提交于 2019-12-08 02:39:35

问题


Let's say I want to display a list of books and their authors. In traditional database design, I would issue a single query to retrieve rows from the Book table as well as the related Author table, a step known as eager fetching. This is done to avoid the dreaded N+1 select problem: If the Author records were retrieved lazily, my program would have to issue a separate query for each author, possibly as many queries as there are books in the list.

Does Google App Engine Datastore provide a similar mechanism, or is the N+1 select problem something that is no longer relevant on this platform?


回答1:


I think you are implicitly asking if Google App Engine supports JOIN to avoid the N+1 select problem.
Google App Engine does not support JOIN directly but lets you define a one to many relationship using ReferenceProperty.

class Author(db.Model):
  name = db.StringProperty()

class Book(db.Model):
  title = db.StringProperty()
  author= db.ReferenceProperty(Author)

In you specific scenario, with two query calls, the first one to get the author:

author = Author.all.filter('name =' , 'fooauthor').get()

and the second one to find all the books of a given author:

books = Book.all().filter('author=', author).fetch(...)

you can get the same result of a common SQL Query that uses JOIN.

The N+1 problem could for example appear when we want to get 100 books, each with its author name:

books = Book.all().fetch(100)
for book in books:
    print book.author.name

In this case, we need to execute 1+100 queries, one to get the books list and 100 to dereference all the authors objects to get the author's name (this step is implicitly done on book.author.name statement).

One common technique to workaround this problem is by using get_value_for_datastore method that retrieves the referenced author's key of a given book without dereferencing it (ie, a datastore fetch):

author_key = Book.author.get_value_for_datastore(book)

There's a brilliant blog post on this topic that you might want to read.
This method, starting from the author_key list, prefetches the authors objects from datastore setting each one to the proper entity book.
Using this approach saves a lot of calls to datastore and practically * avoids the N+1 problem.

* theoretically, on a bookshelf with 100 books written by 100 different authors, we still have to call the datastore 100+1 times

Answering your question:

  • Google App Engine does not support eager fetching
  • There are techniques (not out of the box) that helps to avoid the dreaded N+1 problem


来源:https://stackoverflow.com/questions/4152132/does-gae-datastore-support-eager-fetching

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