Geodjango:使用迁移将PolygonField更改为具有现有数据的MultiPolygonField

时间:2018-03-07 13:42:33

标签: python django migration database-migration geodjango

我有一个PolygonField的模型,它有几十行。我正在尝试将字段更改为MultiPolygonField,但数据仍处于polygon模式。如何将所有现有数据转换为新类型?

models.py

class Region(models.Model):
    class Meta:
        verbose_name = _("region")
        verbose_name_plural = _("regions")

    polygon = models.PolygonField(_("polygon"))  # <== this is going to be MultiPolygon
    name = models.CharField(_("name"), max_length=100)

1 个答案:

答案 0 :(得分:1)

选项1:使用SQL

假设您使用的是postgis,以下SQL可以使用ST_Multi转换您的数据:

ALTER TABLE myapp_region
    ALTER COLUMN polygon TYPE geometry(MultiPolygon, 4326)
    USING ST_Multi(polygon);

不要直接执行此操作,而是运行makemigrations,这将创建一个新的迁移(例如:myapp/migrations/0006_yyyyyyyy.py),类似于:

import django.contrib.gis.db.models.fields
from django.db import migrations


class Migration(migrations.Migration):

    dependencies = [
        ('myapp', '0005_zzzzzzzzzzzzz'),
    ]

    operations = [
        migrations.AlterField(
            model_name='region',
            name='polygon',
            field=django.contrib.gis.db.models.fields.MultiPolygonField(srid=4326),
        ),
    ]

使用AlterField这样的操作封装您的RunSQL操作:

operations = [
    migrations.RunSQL(
        "ALTER TABLE myapp_region ALTER COLUMN polygon type geometry(MultiPolygon, 4326) using ST_Multi(polygon);",
        state_operations=[
            migrations.AlterField(
                model_name='region',
                name='polygon',
                field=django.contrib.gis.db.models.fields.MultiPolygonField(
                    srid=4326),
            ),
        ],
    )
]

现在开始迁移。

选项2:数据迁移

  • 在当前字段旁边创建一个新的geom = models.MultiPolygonField(null=True)字段。
  • 创建并运行迁移以添加新的多字段字段。
  • 创建data migration并使用RunPython复制您的数据:

    for o in Region.objects.all():
        o.geom = MultiPolygon([o.polygon])
        o.save()
    

    (未经测试:您可能可以使用Region.objects.update()

  • models.py中,删除原始字段并移除null=True;创建迁移。
  • 可选:使用其他迁移将geom重命名为polygon