Reputation: 881
I have a model with a PolygonField
, which had dozens of rows. I am trying to change the field to MultiPolygonField
, but data is still in polygon
mode. How can I convert all existing data to the new type?
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)
Upvotes: 1
Views: 1872
Reputation: 30482
Assuming you are using postgis, the following SQL can convert your data by using ST_Multi
:
ALTER TABLE myapp_region
ALTER COLUMN polygon TYPE geometry(MultiPolygon, 4326)
USING ST_Multi(polygon);
Do not execute this directly, instead run makemigrations
which will create a new migration (for example: myapp/migrations/0006_yyyyyyyy.py
) similar to:
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),
),
]
Encapsulate your AlterField
opertaions with a RunSQL
operation like this:
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),
),
],
)
]
and now run your migration.
geom = models.MultiPolygonField(null=True)
field next to your current field.Create a data migration and use RunPython to copy your data:
for o in Region.objects.all():
o.geom = MultiPolygon([o.polygon])
o.save()
(Untested: You might be able to use Region.objects.update()
instead)
models.py
, delete the original field and remove null=True
; create a migration.geom
to polygon
with another migration.Upvotes: 3