Opened 14 years ago
Closed 14 years ago
#13868 closed (duplicate)
Inability to create superuser during syncdb when using GIS fields in AUTH_PROFILE_MODULE
Reported by: | Jason Skicewicz | Owned by: | jbronn |
---|---|---|---|
Component: | GIS | Version: | 1.2 |
Severity: | Keywords: | ||
Cc: | Triage Stage: | Unreviewed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
Overview
I have an AUTH_PROFILE_MODULE that contains a GIS PointField for maintaining a users current location. When a new user is created, I have a post_save signal handler that creates a UserProfile object for the new user. When I run syncdb, and try to create a superuser during the process, I get the following traceback:
Traceback (most recent call last): File "manage.py", line 11, in <module> execute_manager(settings) File "/Library/Python/2.5/site-packages/django/core/management/__init__.py", line 438, in execute_manager utility.execute() File "/Library/Python/2.5/site-packages/django/core/management/__init__.py", line 379, in execute self.fetch_command(subcommand).run_from_argv(self.argv) File "/Library/Python/2.5/site-packages/django/core/management/base.py", line 191, in run_from_argv self.execute(*args, **options.__dict__) File "/Library/Python/2.5/site-packages/django/core/management/base.py", line 218, in execute output = self.handle(*args, **options) File "/Library/Python/2.5/site-packages/django/core/management/base.py", line 347, in handle return self.handle_noargs(**options) File "/Library/Python/2.5/site-packages/django/core/management/commands/syncdb.py", line 103, in handle_noargs emit_post_sync_signal(created_models, verbosity, interactive, db) File "/Library/Python/2.5/site-packages/django/core/management/sql.py", line 185, in emit_post_sync_signal interactive=interactive, db=db) File "/Library/Python/2.5/site-packages/django/dispatch/dispatcher.py", line 162, in send response = receiver(signal=self, sender=sender, **named) File "/Library/Python/2.5/site-packages/django/contrib/auth/management/__init__.py", line 44, in create_superuser call_command("createsuperuser", interactive=True) File "/Library/Python/2.5/site-packages/django/core/management/__init__.py", line 166, in call_command return klass.execute(*args, **defaults) File "/Library/Python/2.5/site-packages/django/core/management/base.py", line 218, in execute output = self.handle(*args, **options) File "/Library/Python/2.5/site-packages/django/contrib/auth/management/commands/createsuperuser.py", line 134, in handle User.objects.create_superuser(username, email, password) File "/Library/Python/2.5/site-packages/django/contrib/auth/models.py", line 133, in create_superuser u = self.create_user(username, email, password) File "/Library/Python/2.5/site-packages/django/contrib/auth/models.py", line 129, in create_user user.save(using=self._db) File "/Library/Python/2.5/site-packages/django/db/models/base.py", line 435, in save self.save_base(using=using, force_insert=force_insert, force_update=force_update) File "/Library/Python/2.5/site-packages/django/db/models/base.py", line 543, in save_base created=(not record_exists), raw=raw) File "/Library/Python/2.5/site-packages/django/dispatch/dispatcher.py", line 162, in send response = receiver(signal=self, sender=sender, **named) File "/usr/local/findmefit/../findmefit/accounts/models.py", line 25, in profile_creation_handler profile, created = UserProfile.objects.get_or_create(user=instance) File "/Library/Python/2.5/site-packages/django/db/models/manager.py", line 135, in get_or_create return self.get_query_set().get_or_create(**kwargs) File "/Library/Python/2.5/site-packages/django/db/models/query.py", line 366, in get_or_create return self.get(**kwargs), False File "/Library/Python/2.5/site-packages/django/db/models/query.py", line 336, in get num = len(clone) File "/Library/Python/2.5/site-packages/django/db/models/query.py", line 81, in __len__ self._result_cache = list(self.iterator()) File "/Library/Python/2.5/site-packages/django/db/models/query.py", line 269, in iterator for row in compiler.results_iter(): File "/Library/Python/2.5/site-packages/django/db/models/sql/compiler.py", line 672, in results_iter for rows in self.execute_sql(MULTI): File "/Library/Python/2.5/site-packages/django/db/models/sql/compiler.py", line 727, in execute_sql cursor.execute(sql, params) File "/Library/Python/2.5/site-packages/django/db/backends/util.py", line 15, in execute return self.cursor.execute(sql, params) File "/Library/Python/2.5/site-packages/django/db/backends/postgresql_psycopg2/base.py", line 44, in execute return self.cursor.execute(query, args) django.db.utils.DatabaseError: column accounts_userprofile.current_location does not exist LINE 1: ...ion_name", "accounts_userprofile"."friends_list", "accounts_... ^
This is due to the fact that the custom SQL commands have not been run yet. If I do a syncdb without creating the superuser in the process, and then create superusers from the command line after a successful syncdb, everything works correctly.
I am using PostgreSQL 8.4.3-1 and PostGIS 1.5.1-1.
Setup
The following assumes that you have a working GeoDjango installation, which I have. This was verified by running the GeoDjango tutorial without fail.
- In settings.py add a profile model
AUTH_PROFILE_MODULE = 'accounts.UserProfile'
- In the application accounts, add the following simple UserProfile model
from django.contrib.auth.models import User from django.contrib.gis.db import models from django.db.models.signals import post_save def profile_creation_handler(sender, instance, created, **kwargs): """ This is a post_save handler on the User class so that we create a user's profile whenever a new User is created. """ if created: profile, created = UserProfile.objects.get_or_create(user=instance) class UserProfile(models.Model): """ UserProfile model with PointField for a users current_location """ user = models.ForeignKey(User, unique=True, editable=False) profile_url = models.URLField(verify_exists=False, blank=True) current_location = models.PointField(blank=True, null=True) objects = models.GeoManager() class Meta: pass def __unicode__(self): return u'%s (%s)' % (self.user, self.profile_url,) def __repr__(self): return '<%s Object: %s (%s)>' % (self.__class__.__name__, self.user, self.profile_url,) post_save.connect(profile_creation_handler, sender=User)
I believe the reason the problem happens is that custom SQL is done after the prompt for creating a super user, which means that the geometry column in UserProfile has not been created yet. This is why if I create super users after syncdb has properly run, everything works correctly. I assigned this to the component GIS, but I believe it could be more related to the order in which things happen during syncdb.
Change History (4)
comment:1 by , 14 years ago
comment:2 by , 14 years ago
Owner: | changed from | to
---|---|
Status: | new → assigned |
I'll accept the ticket for now, but I'm not sure if there will be a patch acceptable for this edge-case scenario that has an easy work-around (run syncdb
first, and create the superuser afterwards):
$ ./manage.py syncdb --noinput $ ./manage.py createsuperuser
From my brief review, the only way to fix this would be to change when the post_syncdb
is emitted, as it is done before the index creation SQL (which is now where the AddGeometryColumn
SQL is actually generated). The side-effects of this 'fix' could be far-reaching have many backwards-incompatible consequences, so for now I would recommend the workaround given above.
comment:4 by , 14 years ago
Resolution: | → duplicate |
---|---|
Status: | assigned → closed |
Actually, this ticket is a duplicate of #13826 because it's the same root issue.
test