Как фильтровать строки с нулевыми ссылками в БД движка приложений Google - PullRequest
3 голосов
/ 07 января 2010

У меня есть Model UnitPattern, который ссылается на другой Model UnitPatternSet

, например

class UnitPattern(db.Model):
    unit_pattern_set = db.ReferenceProperty(UnitPatternSet)

На мой взгляд, я хочу отобразить все UnitPatterns, имеющие ссылки unit_pattern_set как None, но запрос UnitPattern.all (). Filter ("unit_pattern_set =", None) ничего не возвращает, хотя у меня всего 5 UnitPatterns, из которых 2 'unit_pattern_set' установлен и 3 не имеет

, например

print 'Total',UnitPattern.all().count()
print 'ref set',UnitPattern.all().filter("unit_pattern_set !=", None).count()
print 'ref not set',UnitPattern.all().filter("unit_pattern_set =", None).count()

выходы:

Total 5
ref set 2
ref not set 0

Разве сумма запроса 2 и 3 не должна совпадать с запросом 1?

Причина, по-видимому, в том, что я добавил ссылочное свойство unit_pattern_set позже, и эти объекты UnitPattern существовали до этого, но тогда как я могу отфильтровать такие объекты?

1 Ответ

8 голосов
/ 07 января 2010

Это кратко описано в документах :

Индекс содержит только объекты, которые иметь каждое свойство, указанное индекс. Если у субъекта нет свойство, указанное индексом, сущность не появится в индексе, и никогда не будет результатом для запрос, который использует индекс.

Обратите внимание, что хранилище данных App Engine делает Различие между сущностью, которая не обладает собственностью и юридическое лицо, которое обладает собственностью с нулевым значением (Нет). Если ты хочешь каждая сущность, чтобы быть потенциальный результат для запроса, вы можете использовать модель данных, которая назначает значение по умолчанию (например, Нет) для свойства, используемые фильтрами запросов.

В вашем случае у вас есть 3 сущности, у которых вообще не установлено свойство unit_pattern_set (потому что это свойство не было определено в модели во время создания этих сущностей) - поэтому эти свойства не существует в представлении базы данных этого объекта, поэтому этот объект не отображается в индексе этого свойства для объекта такого типа.

Книга Дэна Сандерсона Программирование Google App Engine объясняет это очень подробно на ~ странице 150 (к сожалению, недоступно в предварительном просмотре Google Книги)

Для исправления моделей, которые у вас уже есть, вам нужно будет выполнить итерацию по запросу на UnitPattern (я не проверял следующий код, пожалуйста, проверьте его перед тем, как запускать его на ваших реальных данных):

patterns = UnitPattern.all()
for pattern in patterns:
  if not pattern.unit_pattern_set:
    pattern.unit_pattern_set = None
    pattern.put()

Редактировать: Также в статье Обновление схемы вашей модели обсуждаются стратегии, которые вы можете использовать для обработки таких изменений схемы, как в будущем. Однако эта статья довольно старая, и ее метод требует, чтобы веб-браузер продолжал нажимать на URL, чтобы запустить следующее задание для обновления большего количества записей - теперь, когда существует Task Queues , вы можете использовать ряд задач для создания изменение. Статья об использовании deferred.defer содержит структуру, которую вы можете использовать - она ​​выполняет небольшую работу, перехватывает DeadlineExceededError и использует обработчик для постановки в очередь новой задачи, которая выбирает, где остановилась текущая задача .

...