Opened 6 years ago

Closed 3 months ago

#12400 closed Bug (fixed)

column "X" named in key does not exist error when models.PointField used in unique_together

Reported by: monkut Owned by: claudep
Component: GIS Version: master
Severity: Normal Keywords: 1.9
Cc: chazen@…, ckarrie@… Triage Stage: Ready for checkin
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description (last modified by jbronn)

Hit the following error when trying to use a geometry together with Meta: unique_together.
Using posgresql/PostGIS


class Data(models.Model):
    X = models.PointField(null=True, blank=True)
    Y = models.IntegerField()
    class Meta:
        unique_together = ('X', 'Y')

Exception on trying to syncdb/run test:

Creating table mydata_data
Traceback (most recent call last):
  File "", line 11, in <module>
  File "C:\Python26\lib\site-packages\django\core\management\", line 362, in execute_manager
  File "C:\Python26\lib\site-packages\django\core\management\", line 303, in execute
  File "C:\Python26\lib\site-packages\django\core\management\", line 195, in run_from_argv
    self.execute(*args, **options.__dict__)
  File "C:\Python26\lib\site-packages\django\core\management\", line 222, in execute
    output = self.handle(*args, **options)
  File "C:\Python26\lib\site-packages\django\core\management\commands\", line 23, in handle
    failures = test_runner(test_labels, verbosity=verbosity, interactive=interactive)
  File "C:\Python26\lib\site-packages\django\contrib\gis\tests\", line 135, in run_tests
    create_test_spatial_db(verbosity=verbosity, autoclobber=not interactive)
  File "C:\Python26\lib\site-packages\django\contrib\gis\db\backend\postgis\", line 135, in create_test_spatial_db
    call_command('syncdb', verbosity=verbosity, interactive=interactive)
  File "C:\Python26\lib\site-packages\django\core\management\", line 166, in call_command
    return klass.execute(*args, **defaults)
  File "C:\Python26\lib\site-packages\django\core\management\", line 222, in execute
    output = self.handle(*args, **options)
  File "C:\Python26\lib\site-packages\django\core\management\", line 351, in handle
    return self.handle_noargs(**options)
  File "C:\Python26\lib\site-packages\django\core\management\commands\", line 78, in handle_noargs
psycopg2.ProgrammingError: column "X" named in key does not exist

I checked the sql generated and it seems this problem occurs because the the geometry column is added *after* the initial table is created. And the UNIQUE restriction is applied on initial table creation.

Change History (19)

comment:1 Changed 6 years ago by russellm

  • Component changed from Uncategorized to GIS
  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset
  • Triage Stage changed from Unreviewed to Design decision needed

comment:2 Changed 6 years ago by jbronn

  • Description modified (diff)
  • Owner changed from nobody to jbronn

Unfortunately, the OGC specification requires that the geometry column is added via the AddGeometryColumn stored procedure after the table is defined. There are a few options here:

(1) Modify so that unique_together with geometry columns is created by an ALTER TABLE statement after AddGeometryColumn is called. I think this would require a good amount of re-plumbing in django.db.backends.creation.BaseDatabaseCreation.sql_create_model and possibly some flag on Field itself to indicate which fields are added outside the CREATE TABLE definition.

(2) Use PostGIS 1.5 and the geography column type (which is a normal db column type and put in CREATE TABLE statement, unlike the geometry type). In other words, X = models.PointField(geography=True, null=True, blank=True). This also requires Django 1.2 (or SVN), but you'd be able to use the constraint.

(3) Use another database backend, like MySQL or Oracle, that doesn't create geometries with the AddGeometryColumn stored procedure.

Obviously, (1) is a long-term fix, while (2) and (3) are workarounds for the moment. This is definitely a DDN ticket for the moment.

comment:3 Changed 6 years ago by anonymous

  • Cc chazen@… added

comment:4 Changed 5 years ago by mattmcc

  • Severity set to Normal
  • Type set to Bug

comment:5 Changed 4 years ago by aaugustin

  • UI/UX unset

Change UI/UX from NULL to False.

comment:6 Changed 4 years ago by aaugustin

  • Easy pickings unset

Change Easy pickings from NULL to False.

comment:7 Changed 4 years ago by ckarrie

  • Cc ckarrie@… added
  • Version changed from 1.1 to SVN

Same in Postgis 2.0

comment:8 Changed 3 years ago by aaugustin

  • Triage Stage changed from Design decision needed to Accepted

If this isn't fixed, it should at least be documented.

comment:9 Changed 8 months ago by claudep

  • Has patch set
  • Owner changed from jbronn to claudep
  • Status changed from new to assigned

comment:10 Changed 8 months ago by timgraham

  • Triage Stage changed from Accepted to Ready for checkin

comment:11 Changed 8 months ago by Claude Paroz <claude@…>

  • Resolution set to fixed
  • Status changed from assigned to closed

In 01ec127b:

Fixed #12400 -- Allowed geometry fields in unique_together

Thanks Tim Graham for the review.

comment:12 Changed 8 months ago by timgraham

  • Has patch unset
  • Resolution fixed deleted
  • Status changed from closed to new
  • Triage Stage changed from Ready for checkin to Accepted

Crash on Oracle after this change:

Traceback (most recent call last):
  File "./", line 434, in <module>
  File "./", line 256, in django_tests
  File "/home/jenkins/workspace/django-oracle/database/oragis11/label/trusty/python/python2.7/django/test/", line 210, in run_tests
    old_config = self.setup_databases()
  File "/home/jenkins/workspace/django-oracle/database/oragis11/label/trusty/python/python2.7/django/test/", line 166, in setup_databases
  File "/home/jenkins/workspace/django-oracle/database/oragis11/label/trusty/python/python2.7/django/test/", line 370, in setup_databases
    serialize=connection.settings_dict.get("TEST", {}).get("SERIALIZE", True),
  File "/home/jenkins/workspace/django-oracle/database/oragis11/label/trusty/python/python2.7/django/db/backends/base/", line 71, in create_test_db
  File "/home/jenkins/workspace/django-oracle/database/oragis11/label/trusty/python/python2.7/django/core/management/", line 118, in call_command
    return command.execute(*args, **defaults)
  File "/home/jenkins/workspace/django-oracle/database/oragis11/label/trusty/python/python2.7/django/core/management/", line 398, in execute
    output = self.handle(*args, **options)
  File "/home/jenkins/workspace/django-oracle/database/oragis11/label/trusty/python/python2.7/django/core/management/commands/", line 168, in handle
    self.sync_apps(connection, executor.loader.unmigrated_apps)
  File "/home/jenkins/workspace/django-oracle/database/oragis11/label/trusty/python/python2.7/django/core/management/commands/", line 288, in sync_apps
  File "/home/jenkins/workspace/django-oracle/database/oragis11/label/trusty/python/python2.7/django/db/backends/", line 64, in execute
    return self.cursor.execute(sql, params)
  File "/home/jenkins/workspace/django-oracle/database/oragis11/label/trusty/python/python2.7/django/db/", line 95, in __exit__
    six.reraise(dj_exc_type, dj_exc_value, traceback)
  File "/home/jenkins/workspace/django-oracle/database/oragis11/label/trusty/python/python2.7/django/db/backends/", line 62, in execute
    return self.cursor.execute(sql)
  File "/home/jenkins/workspace/django-oracle/database/oragis11/label/trusty/python/python2.7/django/db/backends/oracle/", line 478, in execute
    return self.cursor.execute(query, self._param_generator(params))
django.db.utils.DatabaseError: ORA-02329: column of datatype ADT cannot be unique or a primary key

comment:13 Changed 8 months ago by claudep

Does that mean that Oracle doesn't support unique indexes on geometry fields? If that's the case, we'll probably need a new database feature. Then the difficulty will be to conditionally create the index during tests. As usual, I'm not able to work on Oracle fixes, but I'm available to discuss/help.

More generally, being able to skip some model import or creation depending on the backend would be useful for other tests too (gis, postgres, etc.).

comment:14 Changed 7 months ago by timgraham

  • Keywords 1.9 added

comment:15 Changed 3 months ago by jtiai

Yes, Oracle doesn't support unique index on geometry fields so this must be resolved so that models and tests are skipped on Oracle by some means.

comment:16 Changed 3 months ago by akaariai

Could you make the unique index definition conditional on used database, and the skip the tests that require the index by normal means? Alternatively you can make the model definition conditional on db, but that requires conditional imports, too.

comment:17 Changed 3 months ago by timgraham

  • Triage Stage changed from Accepted to Ready for checkin

Pull request looks good (pending some cosmetic edits).

comment:18 Changed 3 months ago by Tim Graham <timograham@…>

In 1b8d7eff:

Refs #12400 -- Added supports_geometry_field_unique_index GIS db feature.

comment:19 Changed 3 months ago by timgraham

  • Resolution set to fixed
  • Status changed from new to closed
Note: See TracTickets for help on using tickets.
Back to Top