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

标签 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:使用 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),
        ),
    ]

使用 RunSQL 操作封装您的 AlterField 操作,如下所示:

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

关于python - Geodjango:使用迁移将现有数据的 PolygonField 更改为 MultiPolygonField,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49153381/

相关文章:

python - os.path.exists 使用整数

python - 奇怪的错误 - python manage.py runserver(线程 django-main-thread 中的异常)

ios6 - 自动滑动在 iOS 6 模拟器上有效,但在 iOS 7 上不起作用

python - 为什么不能用另一个函数替换 Python 对象的 __str__ 方法?

python - 停止 minidom 将 < > 转换为 < >

python - 'admin' 不是 Django 1.4 中的注册命名空间

javascript - 如何从 Django 模板标签调用 javascript 函数

php - 将大型网站从 MySQL 切换到 MySQLi

ruby-on-rails - rake 数据库 :migrate - how do I undo all migrations and redo them

python - 为什么在我的类里面使用 __slots__ 不会改变大小?