#26333 closed Bug (fixed)
GIS geometries classes should be deconstructibles.
Reported by: | simondrabble | Owned by: | Nicolas Noé |
---|---|---|---|
Component: | GIS | Version: | 1.8 |
Severity: | Normal | Keywords: | makemigration gis point pointfield |
Cc: | Triage Stage: | Accepted | |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
Given:
from django.contrib.gis.db import models as gis from django.contrib.gis.geos import Point from django.db import models POINT = Point(-104.9903, 39.7392, srid=4326) class PagedModel(models.Model): objects = gis.GeoManager() location = gis.PointField(srid=4326, default=POINT)
then
python manage.py makemigration python manage.py migrate
Observed:
File "./manage.py", line 10, in <module> execute_from_command_line(sys.argv) File "/pyenv/django1.8/lib/python2.7/site-packages/django/core/management/__init__.py", line 354, in execute_from_command_line utility.execute() File "/pyenv/django1.8/lib/python2.7/site-packages/django/core/management/__init__.py", line 346, in execute self.fetch_command(subcommand).run_from_argv(self.argv) File "/pyenv/django1.8/lib/python2.7/site-packages/django/core/management/base.py", line 394, in run_from_argv self.execute(*args, **cmd_options) File "/pyenv/django1.8/lib/python2.7/site-packages/django/core/management/base.py", line 445, in execute output = self.handle(*args, **options) File "/pyenv/django1.8/lib/python2.7/site-packages/django/core/management/commands/migrate.py", line 222, in handle executor.migrate(targets, plan, fake=fake, fake_initial=fake_initial) File "/pyenv/django1.8/lib/python2.7/site-packages/django/db/migrations/executor.py", line 110, in migrate self.apply_migration(states[migration], migration, fake=fake, fake_initial=fake_initial) File "/pyenv/django1.8/lib/python2.7/site-packages/django/db/migrations/executor.py", line 148, in apply_migration state = migration.apply(state, schema_editor) File "/pyenv/django1.8/lib/python2.7/site-packages/django/db/migrations/migration.py", line 115, in apply operation.database_forwards(self.app_label, schema_editor, old_state, project_state) File "/pyenv/django1.8/lib/python2.7/site-packages/django/db/migrations/operations/fields.py", line 62, in database_forwards field, File "/pyenv/django1.8/lib/python2.7/site-packages/django/contrib/gis/db/backends/postgis/schema.py", line 94, in add_field super(PostGISSchemaEditor, self).add_field(model, field) File "/pyenv/django1.8/lib/python2.7/site-packages/django/db/backends/base/schema.py", line 384, in add_field definition, params = self.column_sql(model, field, include_default=True) File "/pyenv/django1.8/lib/python2.7/site-packages/django/contrib/gis/db/backends/postgis/schema.py", line 30, in column_sql column_sql = super(PostGISSchemaEditor, self).column_sql(model, field, include_default) File "/pyenv/django1.8/lib/python2.7/site-packages/django/db/backends/base/schema.py", line 146, in column_sql default_value = self.effective_default(field) File "/pyenv/django1.8/lib/python2.7/site-packages/django/db/backends/base/schema.py", line 211, in effective_default default = field.get_db_prep_save(default, self.connection) File "/pyenv/django1.8/lib/python2.7/site-packages/django/contrib/gis/db/models/fields.py", line 307, in get_db_prep_save return connection.ops.Adapter(self.get_prep_value(value)) File "/pyenv/django1.8/lib/python2.7/site-packages/django/contrib/gis/db/models/fields.py", line 210, in get_prep_value raise ValueError('Cannot use object with type %s for a geometry lookup parameter.' % type(geom).__name__) ValueError: Cannot use object with type float for a geometry lookup parameter.
Expected:
Migration completes successfully.
Hand-editing the generate migration file to use the Point class results in success.
IOW, changing:
field=django.contrib.gis.db.models.fields.PointField(default=(-104.9903, 39.7392), srid=4326),
to
field=django.contrib.gis.db.models.fields.PointField(default=Point(-104.9903, 39.7392, srid=4326)),
resolves the issue.
Change History (8)
comment:1 by , 9 years ago
Component: | Migrations → GIS |
---|---|
Summary: | makemigration on a PointField field with a default value does not use the value's class. → GIS geometries classes should be deconstructibles. |
Triage Stage: | Unreviewed → Accepted |
comment:2 by , 9 years ago
Owner: | changed from | to
---|---|
Status: | new → assigned |
comment:3 by , 9 years ago
Hi,
I just realized I'm not able to reproduce the initial issue. I've tested against 1.8, 1.9.5 and current version.
Should we close the issue? Or continue working to make sure GEOSGeometry
is deconstructible as suggested by charettes, if that has other benefits?
comment:4 by , 9 years ago
I can still reproduce against the master branch.
The Point
is still converted to a tuple of floats (which simply drops the srid
) and migrate
crash if the field's default is actually used (e.g. AddField
instead of CreateModel
where it's simply ignored).
Have a look at this test app for more details: https://github.com/charettes/django-ticketing/commit/dac11b52249e7a061fea81944a5f11e2b92cee86
comment:5 by , 9 years ago
Indeed, I was using CreateModel
in my test app. Thanks for your comment, will do my best to solve this!
comment:6 by , 9 years ago
Has patch: | set |
---|
Just created a pull request for this, testing various geometries with various constructors.
Should I also write more functional tests to make sure the initial issue is solved (and that migration actually works with Point
), or is testing that those are deconstructible
enough?
I think the
GEOSGeometry
class should be deconstructible.Most of its subclasses are converted to
tuple
s by theIterableSerializer
as they define an__iter__()
method.