将现有 AppEngine DataStore 的 IntegerProperty 更改为 FloatProperty
我构建了一个 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)
我需要一种正确的方法来更改此数据存储属性类型,而不更改(删除旧的并添加新的)现有数据。因为它是许多其他表/模型中使用的关键。
谢谢。
I built an appengine application (python) which need to convert existing datastore entities in integer value (100) to float value (100.00) for currency conversion issue.
How's the right way doing this? Since my query returning error when i just change property type in my model.
Old Model:
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)
New Model:
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)
I need a proper way to alter this datastore property type without changing (delete old and add new) existing data. Since it's key used in many others table/model.
Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
最简单的方法是将模型更改为从 db.Expando 继承,并从定义中删除整数属性。然后,加载每个实例并对每个实例执行“instance.foo = float(instance.foo)”,然后将它们保存回数据存储 - 您可能需要为此使用 mapreduce API。最后,使模型再次扩展 db.Model,并将 FloatProperties 添加回来。
不过,您真的、真的不想使用浮动货币:浮动货币很容易受到舍入错误的影响,这意味着您可能会损失(或获得!)金钱。相反,请使用 IntegerProperty 来计算美分的数量。
The easiest way to do this is to change the model to inherit from db.Expando, and delete the integer properties from the definion. Then, load each instance and do "instance.foo = float(instance.foo)" on each, before saving them back to the datastore - you'll probably want to use the mapreduce API for this. Finally, make the model extend db.Model again, and add the FloatProperties back.
You really, really don't want to use a float for currency, though: floats are susceptible to rounding errors, which means you can lose (or gain!) money. Instead, use an IntegerProperty that counts the number of cents.
以下是
Nick Johnson
的答案的示例:之前
:之后
非常之后
:Here is exampe for
Nick Johnson
's answer:Before
:After
Very after
:也许一个好方法是临时创建一个新模型:
然后编写一些脚本、任务或视图,将实例从旧模型转换为临时模型,将整数值转换为浮点数。如果可能的话,请确保复制 ID 和密钥。
更改主模型后,将所有条目从临时模型复制到其中。然后删除临时模型。
这很可能不是最佳方法,并且需要一些手动迁移,尽管没有 South 和应用程序引擎,我真的没有看到一个好的方法来做到这一点。
Maybe a good way is to temporary create a new model:
Then write some script, task or view which convert instances from old model to temporary model, converting the integer values to float. Make sure copying the id's and key's as well if somehow possible.
After change your main model and copy all entries from the temporary one to it. Then remove the temporary model.
This is most likely not the optimal way and requires some manual migration, though without South and on app engine I don't really see a good way to do it.
从数据存储管理界面中的编辑实体页面:
From the Edit Entity page in the data store admin interface: