Вот модель данных, которая может помочь вам:
class Table(db.Model):
name = db.StringProperty(required=True)
owner = db.UserProperty()
column_names = db.StringListProperty()
class Row(db.Model):
values = db.ListProperty(yourtype)
table = db.ReferenceProperty(Table, collection_name='rows')
Мои рассуждения:
Вам действительно не нужен отдельный объект для хранения имен столбцов. Поскольку все столбцы имеют одинаковый тип данных, вам нужно только сохранить имя, а тот факт, что они хранятся в списке, дает вам неявный номер заказа.
Сохраняя значения в списке в объекте Row, вы можете использовать индекс в свойстве column_names , чтобы найти соответствующее значение в свойстве values .
При хранении всех значений для строки вместе в одном объекте нет возможности появления значений в неправильном порядке.
Предостережение emptor:
Эта модель не будет работать хорошо, если к таблице могут быть добавлены столбцы после заполнения данными. Чтобы сделать это возможным, каждый раз, когда добавляется столбец, каждая существующая строка, принадлежащая этой таблице, должна иметь добавленное значение в своем списке values . Если бы было возможно эффективно хранить словари в хранилище данных, это не было бы проблемой, но к списку можно было бы только добавить.
В качестве альтернативы, вы можете использовать Expando ...
Другая возможность состоит в том, что вы можете определить модель Row как Expando, которая позволяет динамически создавать свойства для сущности. Вы можете установить значения столбцов только для столбцов, в которых есть значения, и что вы также можете добавить столбцы в таблицу после того, как в ней есть данные, и ничего не разбивать:
class Row(db.Expando):
table = db.ReferenceProperty(Table, collection_name='rows')
@staticmethod
def __name_for_column_index(index):
return "column_%d" % index
def __getitem__(self, key):
# Allows one to get at the columns of Row entities with
# subscript syntax:
# first_row = Row.get()
# col1 = first_row[1]
# col12 = first_row[12]
value = None
try:
value = self.__dict__[Row.__name_for_column_index]
catch KeyError:
# The given column is not defined for this Row
pass
return value
def __setitem__(self, key, value):
# Allows one to set the columns of Row entities with
# subscript syntax:
# first_row = Row.get()
# first_row[5] = "New values for column 5"
self.__dict__[Row.__name_for_column_index] = value
# In order to allow efficient multiple column changes,
# the put() can go somewhere else.
self.put()