【问题标题】:Geodjango: Change PolygonField to MultiPolygonField with exisiting data using a migrationGeodjango:使用迁移将 PolygonField 更改为具有现有数据的 MultiPolygon Field
【发布时间】:2018-08-15 15:24:11
【问题描述】:

我有一个带有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)

【问题讨论】:

  • 您说您有一个表格,其中有一列类型为“多边形”的列,其中包含数十个“字段”。列没有字段,表有字段。我想大多数人会认为“字段”和“列”指的是同一个东西,但你似乎用它们来描述不同的东西。您的意思是说您有一个名为 Polygon 的表,其中包含数十个字段?这个问题让我有点困惑。您能否发布您的模型、您尝试更改的内容、任何相关代码、您期望的结果以及您实际获得的结果?
  • 添加了我的型号代码@NathanSmith

标签: python django migration database-migration geodjango


【解决方案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),
        ),
    ]

使用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 并进行另一次迁移。

【讨论】:

  • 您的第二个解决方案遇到此错误:Cannot set Region SpatialProxy (MULTIPOLYGON) with value of type:
  • 但第一个有效..如此出色的答案,一百万
  • 关于“Cannot set Region SpatialProxy”错误,请注意从django.contrib.gis.geos导入MultiPolygon。
猜你喜欢
  • 1970-01-01
  • 2017-01-07
  • 2018-03-15
  • 2014-06-21
  • 1970-01-01
  • 2021-07-01
  • 2019-07-14
  • 2021-09-01
  • 2016-10-24
相关资源
最近更新 更多