Я думаю, вы косвенно спрашиваете, поддерживает ли Google App Engine JOIN, чтобы избежать проблемы выбора N+1.
Google App Engine не поддерживает JOIN напрямую, но позволяет определить one to many relationship
с помощью ReferenceProperty.
class Author(db.Model):
name = db.StringProperty()
class Book(db.Model):
title = db.StringProperty()
author= db.ReferenceProperty(Author)
В вашем конкретном сценарии с двумя вызовами запросов первый из них получает автора:
author = Author.all.filter('name =' , 'fooauthor').get()
и второй, чтобы найти все книги данного автора:
books = Book.all().filter('author=', author).fetch(...)
вы можете получить тот же результат обычного SQL-запроса, который использует JOIN.
Например, проблема N+1 может возникнуть, когда мы хотим получить 100 книг, каждая из которых имеет свое имя автора:
books = Book.all().fetch(100)
for book in books:
print book.author.name
В этом случае нам нужно выполнить 1+100 запросов, один для получения списка книг и 100 для разыменования всех объектов авторов для получения имени автора (этот шаг неявно выполняется в операторе book.author.name
).
Одним из распространенных методов обхода этой проблемы является использование метода get_value_for_datastore
, который извлекает указанный ключ автора данной книги без ее разыменования (т. е. выборки из хранилища данных):
author_key = Book.author.get_value_for_datastore(book)
На эту тему есть блестящая запись в блоге, которую вы можете хотите прочитать.
Этот метод, начиная со списка author_key
, предварительно выбирает объекты авторов из хранилища данных, устанавливая для каждого из них соответствующую книгу сущностей.
Использование этого подхода экономит много вызовов хранилища данных и практически * позволяет избежать проблемы N+1.
* теоретически, на книжной полке со 100 книгами, написанными 100 разными авторами, нам все равно придется обращаться к хранилищу данных 100+1 раз
Отвечая на ваш вопрос:
- Google App Engine не поддерживает упреждающую выборку
- Существуют методы (нестандартные), которые помогают избежать ужасной проблемы N+1.
person
systempuntoout
schedule
11.11.2010