当前位置: 首页 > 面试题库 >

更改NDB字段的属性类型时迁移数据

花飞扬
2023-03-14
问题内容

假设我最初创建了一个ndb.Model,并且想要更改字段的ndb属性类型(例如,将IntegerProperty更改为StringProperty),但是想要转换存储在该字段中的当前数据,以免丢失该数据。一种方法是简单地创建一个新的字段名,然后使用脚本迁移数据,但是还有其他更方便的方法来完成此操作吗?

例如,假设我有以下模型:

class Car(ndb.Model):
    name = ndb.StringProperty()
    production_year = ndb.IntegerProperty()

我存储了一个实体实例:

c = new Car()
c.name = "Porsche"
c.production_year = 2013

并希望将production_year更改为ndb.StringProperty()而不“丢失”我设置的值(该值仍然存在,但无法检索)。如果仅将production_year更改为ndb.StringProperty()的实例,则字段值不会报告有意义的值,因为类型不匹配。

因此,如果我将模型更改为:

class Car(ndb.Model):
    name = ndb.StringProperty()
    production_year = ndb.StringProperty()

尝试使用点符号检索字段将导致值None。任何人都会遇到这种情况,您能解释一下您为解决该问题所做的工作吗?谢谢。


问题答案:

您如何处理此问题将取决于您拥有多少实体。如果您在10000个实体中说相对较少的实体,那么我将使用remote_api并从数据存储中检索原始基础数据并直接操作数据,然后不使用模型将其写回。例如,这将获取原始实体,并且可以像字典一样访问属性。此代码是从较低级别的appengine
SDK代码中提取的。

from google.appengine.api import datastore
from google.appengine.api import datastore_errors

def get_entities(keys):
    rpc = datastore.GetRpcFromKwargs({})
    keys, multiple = datastore.NormalizeAndTypeCheckKeys(keys)
    entities = None
    try:
        entities = datastore.Get(keys, rpc=rpc)
    except datastore_errors.EntityNotFoundError:
        assert not multiple

    return entities

def put_entities(entities):
    rpc = datastore.GetRpcFromKwargs({})
    keys = datastore.Put(entities, rpc=rpc)
    return keys

您将按以下方式使用它(对于此示例,我正在使用访存来简化代码)

x = Car.query(keys_only=True).fetch(100)
results = get_entities([i.to_old_key() for i in x])

for i in results:
    i['production_year'] = unicode(i['production_year'])

put_entities(results)

这是我拥有的旧代码,并datastore.NormalizeAndTypeCheckKeys采用了旧的db样式键,但我没有看到ndb样式键具有等效的功能,但这确实有效。(只是测试过;-)

这种方法使您无需部署任何新代码即可迁移数据。
如果您有数百万个实体,则应查看其他处理方法,即使用此代码和使用mapreduce。



 类似资料:
  • 在laravel 5.7/mysql 5应用程序中,我想将默认值设置为timestamp字段(创建时未设置): 但我有一个错误: 通常,我对时间戳字段没有任何问题,我假设该方法- 修改块#1:我把它放在我的作曲者那里了。json: 通过谷歌搜索,我发现我还需要安装marktopper/dbal时间戳类型https://github.com/art-institute-of-chicago/data

  • 问题内容: 我正在尝试学习一些Flask,并且正在使用Flask-Migrate 1.6.0 所以我做了一个看起来像这样的模型 然后我将其更改为完全相同的东西,除了这一行: 当我运行我的 命令,它不会检测列类型的更改。我已经阅读了它,我知道当我更改env.py并添加compare_type = True变量时,它应该将其选中。但是我这样做无济于事,该方法现在看起来像这样 好的,所以我的问题是: 更

  • SQLAlchemy变更日志和迁移指南现在集成在主文档中。 当前迁移指南 SQLAlchemy 1.4有什么新功能? SQLAlchemy 2.0概述和状态 迁移到Alchemy 更改日志 1.4变更日志 1.3换热器 1.2换热器 1.1换热器 1换热器 0.9换热器 0.8换热器 0.7换热器 0.6换热器 0.5换热器 0.4换热器 0.3换热器 0.2换热器 0.1换热器 旧的迁移指南 S

  • 问题内容: 我们需要将某些列的数据类型从int更改为bigint。不幸的是,其中一些表很大,大约有7-10百万行(但不宽)。 Alter表alter列将永远保留在这些表上。有没有更快的方法来实现这一目标? 问题答案: 巧合的是,大约3个小时前,我不得不做一些非常相似的事情。该表是3500万行,它相当宽,并且花了很多时间才能做到这一点: 这就是我最终得到的结果: 这次,这些陈述几乎是即时的。(在速度

  • 嗨,为了保持向后兼容性,可以更改协议缓冲区中字段的数据类型吗。例如 旧消息 所以基本上我没有更改字段的标签号,也没有重命名它,但我更改了数据类型。那么这是向后兼容的吗?如果一个应用程序获得了一个用以前的模式创建的旧proto对象,它可以通过这个新模式创建的对象进行解析吗?

  • 我有一个MyClass,它的属性类型为MyAttribute。该类由MySubClass继承,其属性类型为MySubAttribute。MySubAttribute是MyAttribute的子类: 现在假设我有以下代码: 如何生成MySubAttribute类型的返回值?