我应该如何从bradjasper的django-jsonfield升级到Django的内置jsonfield?

Sar*_*ser 3 django postgresql json jsonb

我有一个使用bradjasper django-jsonfield软件包的Postgres 9.4/Django 1.8数据库.(参见https://github.com/bradjasper/django-jsonfield)它运行良好,但我想升级现有数据以使用Postgres 9.6和Django 1.9的内置JSONField.(请参阅https://docs.djangoproject.com/en/1.10/ref/contrib/postgres/fields/#jsonfield)这将允许更强大的JSON内容搜索.

如何将旧数据库升级到新数据库?

我尝试了什么:我尝试插入一对架构迁移

  • 将bradjasper JSONField转换为TextField,包括运行迁移.(这不应该更改数据库,因为bradjasper将数据存储为字符串.)
  • 运行Django的dumpdata命令.
  • 更新了Postgres和Django版本.
  • 运行迁移将TextField转换为Django的JSONField.(这应该是在数据库中,一个变化从一个textjsonjsonb).
  • 运行Django的loaddata命令.这给出了一个错误:u"[] (type <type 'unicode'>) is not a valid list for field url_methods"]: (myapp.mytable:pk=1) field_value was '[]' 我正在看postgresql将JSON迁移到JSONB并将PostgreSQL JSON列升级到JSONB?但我希望尽量减少自定义SQL.

all*_*aps 7

首先升级Postgres.如果所有的工作升级Django.

只有当一切按预期工作时,您才能开始编写现场迁移.

你想要去:

from jsonfield import JSONField

class MyModel(models.Model):
  json = JSONField()
Run Code Online (Sandbox Code Playgroud)

至:

from django.contrib.postgres.fields import JSONField

class MyModel(models.Model):
  json = JSONField()
Run Code Online (Sandbox Code Playgroud)

脚步:

  1. 添加名为的新Postgres JSON字段json_new.
  2. 进行迁移.不要迁移.
  3. 深入了解迁移文件并编写数据迁移(RunPython)以填充新的json字段.
  4. 进行迁移.
  5. 删除旧字段.删除旧导入.
  6. 进行迁移,迁移.
  7. 将新字段重命名为旧字段名称.json_new> json.
  8. 进行迁移,迁移.
  9. 完成.

步骤1:

使用import ... as ...防止碰撞.您的模型将如下所示:

from jsonfield import JSONField as OldJSONField
from django.contrib.postgres.fields import JSONField

class MyModel(models.Model):
  json = OldJSONField()
  json_new = JSONField()
Run Code Online (Sandbox Code Playgroud)

第3步:

您需要RunPython在迁移中查看https://docs.djangoproject.com/en/1.10/ref/migration-operations/#runpython 还要注意如何导入模型.

实际的数据迁移将类似于:

for obj in MyModel.objects.all()
    obj.json_new = obj.json  
    obj.save()
Run Code Online (Sandbox Code Playgroud)

第4 - 7步:

确保为删除和重命名创建单独的迁移.如果您执行所有代码更改并创建单个迁移,那么Django会认为您已删除json_new.但是你想放弃json并重命名json_newjson.虽然小,但重要的区别.

减少迁移步骤并不困难.但这需要手工编写一些代码.我很懒,喜欢Django给我写这段代码.

  • 您可以使用`F`表达式通过单个查询在`RunPython`中执行数据迁移:`MyModel.objects.update(json_new = F('json'))` (2认同)