Связь между сущностями в GAE?

Добрый вечер.


Решил попробовать GAE и возникла следующая проблема:

Имеется 2 сущности: статья и категории статьи. Категории статьи содержат только одно поле с их описанием.

Во время создания статьи присутствует выбор категории из selectа.


Собственно, вопрос:

Как лучше их связать между собой?


1. Добавлять поле id вроде как не кошерно (поправьте, если не так), есть вариант использовать код вида:

[(category.key().id(), category.title) for category in ArticleCategory.all()]

а в самом объекте статьи хранить int

2. Использовать db.ReferenceProperty? Но тогда я не совсем понимаю, как заполнить SelectField из

WTForms


Спасибо.


P.S. Скорее всего получилось сумбурно, извиняйте. Если надо будет — дополню

P.S.S. и второй вопрос — просьба ткуть носом, где в доке написано как изменяется datastore при измении модели (читай — было 3 поля, одно переименовал — остались ли старые данные с поля и надо-ли их как-то мигрировать?)
  • Вопрос задан
  • 2738 просмотров
Решения вопроса 1
xSkyFoXx
@xSkyFoXx
Вы немного путаете реляционные базы данных и datastore, пытаюясь применить свои знания о первых в приложении ко второй. Попытаюсь ответить на ваш вопрос.
Datastore, по сути своей не является реляционной базой данных. Она относится к NoSQL базам, и больше всего похода на модель объектно-ориентированной БД. Любая запись в datastore представляет из себя самодостаточную сущность (Entity), которая состоит из набора атрибутов (Property, вольный перевод). Модели, которые вы наследуете для создания записей можно считать чем-то (хотя и очень отдалённо) похожим на фабрики функций. Т.е. модель просто позволяют вам «сконструировать» набор (группу) подобных объектов. Ключевое слово «подобных». Никаких требований на одинаковость не некладывается. Такого понятия как «таблица» и её «поля» попросту нет.
Представим что вы написали модель:
class Article(db.Model):
title = db.PropertyString()
author = db.PropertyString()
body = db.PropertyString()

И создали 2 экземпляра:
art1 = Article(title = 'First title', autor = 'Sechspir')
art1.put()
art2 = Article(title = 'First title', body = 'Second article body')
art2.put()

То в базе каждый из объектов будет содержать информацию о всего 2х атрибутах! Никаких, условно говоря, «пустых столбцов» не будет. Это связано с архитектурой хранилища GAE. Дело в том, что никаких ограничений или требований на обработку запросов на одном сервере, или хранения данных на одном сервере, или что одно железо ответить на 2 последовательных запроса пользователя — нет. Кроме того, ваши 2 идущих од ряд запроса могу обработать даже 2 разных датацента.
Какой же выход существует, как однозначно идентифицировать какую-то структуру? Вы, наверно, обратили внимание, что каждая из записей имеет ключ? Это тот самый уникальный идентификатор, который позволяет отыскать ваши данные в датацентрах. Единственный уникальный параметр системы, «размазанной» на миллионы машин.
Ок. Теперь к практике.
1) Да, действительно, использовать ReferenceProperty — самый «кошерный способ». Он позволит Вам находить нужный объект по ссыке ключей.
2) Нет, никаких миграций делать не надо. Здесь проявдяется суть динамичности структур. Вы можете добавлять и удалять property «на лету». И любой из объектов может иметь свой, уникальный набор. Это не породит избыточности в хранилищи. Мы же храним объекты, а их ключи — ссылки, где эти объекты можно взять.
3) Как заполнить SelectField? Сделайте предварительную выборку через .filter() и возьмите через .fetch() ровно столько объектов, сколько вам надо.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы