Вы немного путаете реляционные базы данных и 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() ровно столько объектов, сколько вам надо.