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

时间:2017-01-16 19:06:18

标签: json django postgresql jsonb

我有一个使用bradjasper的private void ComboBoxAddItem(string item) { string[] ComboBoxRows = Properties.Settings.Default.ComboBoxItems.Split('|'); bool ItemAlreadyExists = false; foreach (string Row in ComboBoxRows) { if (Row == item) ItemAlreadyExists = true; } if (!ItemAlreadyExists) { parent.ComboBoxSelectedProfile.Items.Add(item); string ComboBoxSavedProfileAsString = TxtProfileName.Text + "|"; Properties.Settings.Default.ComboBoxItems = Properties.Settings.Default.ComboBoxItems + ComboBoxSavedProfileAsString; Properties.Settings.Default.Save(); } } 包的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的django-jsonfield命令。
  • 更新了Postgres& Django版本。
  • 运行迁移以将TextField转换为Django的JSONField。 (这应该是数据库中的更改,从dumpdatatextjson。)
  • 运行Django的jsonb命令。这会产生如下错误:loaddata 我正在查看postgresql migrating JSON to JSONBUpgrade PostgreSQL JSON column to JSONB?,但我希望尽量减少自定义SQL。

2 个答案:

答案 0 :(得分:7)

首先升级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()

步骤:

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

    第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一样为我写这段代码。

答案 1 :(得分:4)

来自@tometzky的ALTER COLUMN命令Upgrade PostgreSQL JSON column to JSONB? 做到这一点令人惊讶的小麻烦:

  • sudo -u postgres psql -c' ALTER TABLE mytable ALTER COLUMN" myfield" TYPE jsonb USING" myfield" :: text :: jsonb;' MyDatabase的

我不需要Django的loaddata / dumpdata命令或自定义迁移。

我确实有一些问题让pg_upgrade以我想要的方式工作,因为它不在默认路径上,并且想要在升级期间更改Postgres使用的端口。为了解决那个,我做了以下事情:

  • pg_ctl -D /etc/postgresql/9.4/main/ stop
  • 在postgresql.conf上使用sed来更改它使用的端口
  • 安装Postgres 9.6
  • pg_ctl -D /etc/postgresql/9.6/main/ stop
  • cd / var / log / postgresql
  • 运行pg_upgrade
  • cd回到原始工作目录
  • apt-get -y remove postgresql-9.4 postgresql-client-9.4 postgresql-server-dev-9.4
  • service postgresql start