Измените IntegerProperty на FloatProperty существующего хранилища данных AppEngine - PullRequest
5 голосов
/ 20 января 2011

Я создал приложение appengine (python), которое должно преобразовывать существующие сущности хранилища данных в целочисленное значение (100) в значение с плавающей запятой (100.00) для проблемы конвертации валюты. Как правильно это сделать? Так как мой запрос возвращает ошибку, когда я просто изменяю тип свойства в моей модели.

Старая модель:

class Learn(search.SearchableModel):
    pid = db.ReferenceProperty(Product, collection_name='picks')
    title = db.StringProperty()
    description = db.TextProperty()
    order = db.IntegerProperty()
    cost = db.IntegerProperty(default=0)
    cost1 = db.IntegerProperty(default=0)

Новая модель:

class Learn(search.SearchableModel):
    pid = db.ReferenceProperty(Product, collection_name='picks')
    title = db.StringProperty()
    description = db.TextProperty()
    order = db.IntegerProperty()
    cost = db.FloatProperty(default=0.000)
    cost1 = db.FloatProperty(default=0.000)

Мне нужен правильный способ изменить этот тип свойства хранилища данных без изменения (удаления старых и добавления новых) существующих данных. Так как этот ключ используется во многих других таблицах / моделях.

Спасибо.

Ответы [ 4 ]

12 голосов
/ 20 января 2011

Самый простой способ сделать это - изменить модель для наследования от db.Expando и удалить целочисленные свойства из определения. Затем загрузите каждый экземпляр и выполните «instance.foo = float (instance.foo)» для каждого, прежде чем сохранять их обратно в хранилище данных - вы, вероятно, захотите использовать для этого API mapreduce. Наконец, снова заставьте модель расширить db.Model и добавьте обратно FloatProperties.

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

7 голосов
/ 25 декабря 2011

Вот экзамен для Nick Johnson ответа :

Before:

class Person(db.Model):
    name = db.StringProperty()
    age = db.StringProperty() #this will go to int

After

class Person(db.Expando):
    pass

for person in Person.all():
    person.age = int(person.age)
    person.put()

Very after:

class Person(db.Model):
    name = db.StringProperty()
    age = db.IntegerProperty() 
0 голосов
/ 04 апреля 2011

На странице редактирования объекта в интерфейсе администратора хранилища данных:

Введите информацию для объекта ниже.Если вы хотите изменить тип свойства, установите для него значение Null, сохраните объект, снова отредактируйте объект и измените тип

0 голосов
/ 20 января 2011

Возможно, хороший способ - временно создать новую модель:

class LearnTemp(search.SearchableModel):
    pid = db.ReferenceProperty(Product, collection_name='picks')
    title = db.StringProperty()
    description = db.TextProperty()
    order = db.IntegerProperty()
    order = db.IntegerProperty()
    cost = db.FloatProperty(default=0.000)
    cost1 = db.FloatProperty(default=0.000)

Затем напишите некоторый скрипт, задачу или представление, которые преобразуют экземпляры из старой модели во временную модель, преобразовывая целочисленные значения в плавающие. Убедитесь, что скопировали идентификаторы и ключи, если это возможно.

После изменения основной модели и копирования в нее всех записей из временной. Затем удалите временную модель.

Скорее всего, это не оптимальный способ и требует некоторой ручной миграции, хотя без South и без движка приложения я не вижу хорошего способа сделать это.

...