#12400: column "X" named in key does not exist error when models.PointField 
used in
unique_together
---------------------------------------------+------------------------------
          Reporter:  monkut                  |         Owner:  jbronn
            Status:  new                     |     Milestone:        
         Component:  GIS                     |       Version:  1.1   
        Resolution:                          |      Keywords:        
             Stage:  Design decision needed  |     Has_patch:  0     
        Needs_docs:  0                       |   Needs_tests:  0     
Needs_better_patch:  0                       |  
---------------------------------------------+------------------------------
Changes (by jbronn):

  * owner:  nobody => jbronn

Old description:

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

> Model:
>

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

> Exception on trying to syncdb/run test:
> {{{
> Creating table mydata_data
> Traceback (most recent call last):
>   File "manage.py", line 11, in <module>
>     execute_manager(settings)
>   File "C:\Python26\lib\site-
> packages\django\core\management\__init__.py", line 362, in
> execute_manager
>     utility.execute()
>   File "C:\Python26\lib\site-
> packages\django\core\management\__init__.py", line 303, in execute
>     self.fetch_command(subcommand).run_from_argv(self.argv)
>   File "C:\Python26\lib\site-packages\django\core\management\base.py",
> line 195, in run_from_argv
>     self.execute(*args, **options.__dict__)
>   File "C:\Python26\lib\site-packages\django\core\management\base.py",
> line 222, in execute
>     output = self.handle(*args, **options)
>   File "C:\Python26\lib\site-
> packages\django\core\management\commands\test.py", line 23, in handle
>     failures = test_runner(test_labels, verbosity=verbosity,
> interactive=interactive)
>   File "C:\Python26\lib\site-
> packages\django\contrib\gis\tests\__init__.py", 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\creation.py", line 135, in
> create_test_spatial_db
>     call_command('syncdb', verbosity=verbosity, interactive=interactive)
>   File "C:\Python26\lib\site-
> packages\django\core\management\__init__.py", line 166, in call_command
>     return klass.execute(*args, **defaults)
>   File "C:\Python26\lib\site-packages\django\core\management\base.py",
> line 222, in execute
>     output = self.handle(*args, **options)
>   File "C:\Python26\lib\site-packages\django\core\management\base.py",
> line 351, in handle
>     return self.handle_noargs(**options)
>   File "C:\Python26\lib\site-
> packages\django\core\management\commands\syncdb.py", line 78, in
> handle_noargs
>     cursor.execute(statement)
> 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.

New description:

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


 Model:


 {{{
 #!python
 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 "manage.py", line 11, in <module>
     execute_manager(settings)
   File "C:\Python26\lib\site-packages\django\core\management\__init__.py",
 line 362, in execute_manager
     utility.execute()
   File "C:\Python26\lib\site-packages\django\core\management\__init__.py",
 line 303, in execute
     self.fetch_command(subcommand).run_from_argv(self.argv)
   File "C:\Python26\lib\site-packages\django\core\management\base.py",
 line 195, in run_from_argv
     self.execute(*args, **options.__dict__)
   File "C:\Python26\lib\site-packages\django\core\management\base.py",
 line 222, in execute
     output = self.handle(*args, **options)
   File "C:\Python26\lib\site-
 packages\django\core\management\commands\test.py", line 23, in handle
     failures = test_runner(test_labels, verbosity=verbosity,
 interactive=interactive)
   File "C:\Python26\lib\site-
 packages\django\contrib\gis\tests\__init__.py", 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\creation.py", line 135, in
 create_test_spatial_db
     call_command('syncdb', verbosity=verbosity, interactive=interactive)
   File "C:\Python26\lib\site-packages\django\core\management\__init__.py",
 line 166, in call_command
     return klass.execute(*args, **defaults)
   File "C:\Python26\lib\site-packages\django\core\management\base.py",
 line 222, in execute
     output = self.handle(*args, **options)
   File "C:\Python26\lib\site-packages\django\core\management\base.py",
 line 351, in handle
     return self.handle_noargs(**options)
   File "C:\Python26\lib\site-
 packages\django\core\management\commands\syncdb.py", line 78, in
 handle_noargs
     cursor.execute(statement)
 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.

Comment:

 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.

-- 
Ticket URL: <http://code.djangoproject.com/ticket/12400#comment:2>
Django <http://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/django-updates?hl=en.

Reply via email to