我有一个使用 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。 (这应该是数据库中的更改,从
text
或json
到jsonb
。) - 运行 Django 的
loaddata
命令。这会产生如下错误:u"[] (type <type 'unicode'>) is not a valid list for field url_methods"]: (myapp.mytable:pk=1) field_value was '[]'
我在看 postgresql migrating JSON to JSONB和 Upgrade PostgreSQL JSON column to JSONB?但我希望尽量减少自定义 SQL。
最佳答案
先升级 Postgres。如果一切正常,请升级 Django。
只有当一切都按预期进行时,您才能开始编写现场迁移。
你想从:
from jsonfield import JSONField
class MyModel(models.Model):
json = JSONField()
收件人:
from django.contrib.postgres.fields import JSONField
class MyModel(models.Model):
json = JSONField()
步骤:
- 添加名为
json_new
的新 Postgres JSON 字段。 - 进行迁移。不要迁移。
- 深入研究迁移文件并编写数据迁移 (RunPython) 以填充新的 json 字段。
- 进行迁移。
- 删除旧字段。删除旧导入。
- 进行迁移,迁移。
- 将新字段重命名为旧字段名称。
json_new
>json
. - 进行迁移,迁移。
- 完成。
第一步:
使用 import ... as ...
来防止冲突。您的模型将如下所示:
from jsonfield import JSONField as OldJSONField
from django.contrib.postgres.fields import JSONField
class MyModel(models.Model):
json = OldJSONField()
json_new = JSONField()
第 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()
第 4 - 7 步:
确保为删除和重命名创建单独的迁移。如果您更改了所有代码并创建了一个迁移,那么 Django 会认为您删除了 json_new
。但是您想删除 json
并将 json_new
重命名为 json
。微小但重要的区别。
减少迁移步骤并不难。但这需要手动编写一些代码。我很懒,喜欢 Django 帮我写这段代码。
关于json - 我应该如何从 bradjasper 的 django-jsonfield 升级到 Django 的内置 jsonfield?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41683385/