Opened 7 years ago

Closed 19 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: Claude Paroz
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 7 years ago by Russell Keith-Magee

Component: UncategorizedGIS
Triage Stage: UnreviewedDesign decision needed

comment:2 Changed 7 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 7 years ago by anonymous

Cc: chazen@… added

comment:4 Changed 6 years ago by Matt McClanahan

Severity: Normal
Type: Bug

comment:5 Changed 5 years ago by Aymeric Augustin

UI/UX: unset

Change UI/UX from NULL to False.

comment:6 Changed 5 years ago by Aymeric Augustin

Easy pickings: unset

Change Easy pickings from NULL to False.

comment:7 Changed 5 years ago by Christian Karrié

Cc: ckarrie@… added
Version: 1.1SVN

Same in Postgis 2.0

comment:8 Changed 4 years ago by Aymeric Augustin

Triage Stage: Design decision neededAccepted

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

comment:9 Changed 2 years ago by Claude Paroz

Has patch: set
Owner: changed from jbronn to Claude Paroz
Status: newassigned

comment:10 Changed 2 years ago by Tim Graham

Triage Stage: AcceptedReady for checkin

comment:11 Changed 2 years ago by Claude Paroz <claude@…>

Resolution: fixed
Status: assignedclosed

In 01ec127b:

Fixed #12400 -- Allowed geometry fields in unique_together

Thanks Tim Graham for the review.

comment:12 Changed 2 years ago by Tim Graham

Has patch: unset
Resolution: fixed
Status: closednew
Triage Stage: Ready for checkinAccepted

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 2 years ago by Claude Paroz

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 23 months ago by Tim Graham

Keywords: 1.9 added

comment:15 Changed 19 months ago by Jani Tiainen

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 19 months ago by Anssi Kääriäinen

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 19 months ago by Tim Graham

Triage Stage: AcceptedReady for checkin

Pull request looks good (pending some cosmetic edits).

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

In 1b8d7eff:

Refs #12400 -- Added supports_geometry_field_unique_index GIS db feature.

comment:19 Changed 19 months ago by Tim Graham

Resolution: fixed
Status: newclosed
Note: See TracTickets for help on using tickets.
Back to Top