将现有 AppEngine DataStore 的 IntegerProperty 更改为 FloatProperty

发布于 2024-10-13 16:56:30 字数 897 浏览 3 评论 0原文

我构建了一个 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

苦行僧 2024-10-20 16:56:30

最简单的方法是将模型更改为从 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.

煮茶煮酒煮时光 2024-10-20 16:56:30

以下是 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() 

Here is exampe for Nick Johnson's answer:

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() 
空城旧梦 2024-10-20 16:56:30

也许一个好方法是临时创建一个新模型:

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 和应用程序引擎,我真的没有看到一个好的方法来做到这一点。

Maybe a good way is to temporary create a new model:

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)

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.

明媚殇 2024-10-20 16:56:30

从数据存储管理界面中的编辑实体页面:

输入实体的信息
以下。如果您想更改
属性的类型,将其设置为Null,保存
实体,再次编辑实体,然后
更改类型

From the Edit Entity page in the data store admin interface:

Enter information for the entity
below. If you'd like to change a
property's type, set it to Null, save
the entity, edit the entity again, and
change the type

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文