将现有AppEngine DataStore的IntegerProperty更改为FloatProperty
我创建了一个应用程序(用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 个回答
0
也许一个好办法是暂时创建一个新的模型:
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)
然后写一些脚本、任务或者视图,把旧模型中的实例转换到这个临时模型里,把整数值转换成浮点数。如果可能的话,确保也复制ID和键。
在修改你的主模型后,把所有条目从临时模型复制到主模型里。然后删除这个临时模型。
这可能不是最优的办法,需要一些手动迁移,不过在没有South和在应用引擎上,我实在想不到更好的方法了。
7
这里是 Nick Johnson
的一个 回答 的例子:
之前
:
class Person(db.Model):
name = db.StringProperty()
age = db.StringProperty() #this will go to int
之后
class Person(db.Expando):
pass
for person in Person.all():
person.age = int(person.age)
person.put()
非常之后
:
class Person(db.Model):
name = db.StringProperty()
age = db.IntegerProperty()
12
最简单的方法是把模型改成从 db.Expando 继承,然后把定义中的整数属性删掉。接着,加载每个实例,然后对每个实例执行 "instance.foo = float(instance.foo)",在保存回数据存储之前,你可能想用 mapreduce API 来处理这个。最后,再把模型改回继承 db.Model,并把 FloatProperties 加回来。
不过,真的不建议用浮点数来表示货币,因为浮点数容易出现四舍五入的错误,这样可能会导致你损失(或者多出!)钱。更好的做法是用 IntegerProperty 来表示金额,计算的是美分的数量。