#9457 closed (invalid)
ContextType in of limit_choices_to clause causing error during initial syncdb
Reported by: | Owned by: | nobody | |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | 1.0 |
Severity: | Keywords: | contexttype, database | |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
I'm getting the following error (on an empty database):
$ python manage.py syncdb ... (traceback) ... sqlite3.OperationalError: no such table: django_content_type
My INSTALLED_APPS includes ('django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.admin', 'django.contrib.sites', ..., 'Pl', 'Proc')
The offending line seems to be:
# pl/models.py proc = models.ForeignKey(BaseModel, limit_choices_to={ 'content_type': ContentType.objects.get_for_model(Proc) }) # where class Proc(BaseModel): # ...
The traceback is as follows (modified slightly to simplify class names):
Traceback (most recent call last): File "./manage.py", line 11, in <module> execute_manager(settings_web) File "/Library/Python/2.5/site-packages/django/core/management/__init__.py", line 340, in execute_manager utility.execute() File "/Library/Python/2.5/site-packages/django/core/management/__init__.py", line 295, in execute self.fetch_command(subcommand).run_from_argv(self.argv) File "/Library/Python/2.5/site-packages/django/core/management/base.py", line 77, in run_from_argv self.execute(*args, **options.__dict__) File "/Library/Python/2.5/site-packages/django/core/management/base.py", line 95, in execute self.validate() File "/Library/Python/2.5/site-packages/django/core/management/base.py", line 122, in validate num_errors = get_validation_errors(s, app) File "/Library/Python/2.5/site-packages/django/core/management/validation.py", line 28, in get_validation_errors for (app_name, error) in get_app_errors().items(): File "/Library/Python/2.5/site-packages/django/db/models/loading.py", line 128, in get_app_errors self._populate() File "/Library/Python/2.5/site-packages/django/db/models/loading.py", line 57, in _populate self.load_app(app_name, True) File "/Library/Python/2.5/site-packages/django/db/models/loading.py", line 72, in load_app mod = __import__(app_name, {}, {}, ['models']) File "/Users/brian/dev/trunk/apps/ple/models.py", line 238, in <module> class Ple(models.Model): File "/Users/brian/dev/trunk/apps/ple/models.py", line 246, in Pl limit_choices_to={ 'content_type': ContentType.objects.get_for_model(Proc) }) File "/Library/Python/2.5/site-packages/django/contrib/contenttypes/models.py", line 28, in get_for_model defaults = {'name': smart_unicode(opts.verbose_name_raw)}, File "/Library/Python/2.5/site-packages/django/db/models/manager.py", line 96, 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 326, in get_or_create return self.get(**kwargs), False File "/Library/Python/2.5/site-packages/django/db/models/query.py", line 298, in get num = len(clone) File "/Library/Python/2.5/site-packages/django/db/models/query.py", line 154, 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 self.query.results_iter(): File "/Library/Python/2.5/site-packages/django/db/models/sql/query.py", line 206, in results_iter for rows in self.execute_sql(MULTI): File "/Library/Python/2.5/site-packages/django/db/models/sql/query.py", line 1700, in execute_sql cursor.execute(sql, params) File "/Library/Python/2.5/site-packages/django/db/backends/util.py", line 19, in execute return self.cursor.execute(sql, params) File "/Library/Python/2.5/site-packages/django/db/backends/sqlite3/base.py", line 167, in execute return Database.Cursor.execute(self, query, params) sqlite3.OperationalError: no such table: django_content_type
Python: 2.5.1
OS: OS X
Cheers!
Change History (7)
comment:1 by , 16 years ago
comment:2 by , 16 years ago
Ugh. Neglect the last comment. You can't get around it this way, you need to add the limit_choices_to *after* you create the target models. And, frankly, it wouldn't make sense any other way because the content types framework has to look it up in the db, this ticket should probably be closed as invalid.
comment:3 by , 16 years ago
Resolution: | → invalid |
---|---|
Status: | new → closed |
If your own apps require something else to be installed/set up before they can work, then the solution is to set up that thing before you try to use or install your apps.
comment:4 by , 16 years ago
For what it's worth, I strongly disagree with the notion that initializing a database should result in a catastrophic error because there are tables with fields that use limit_choices_to. It obliges developers using Django to implement extra (and arguably arbitrary) development and deployment procedures. In other words, it pushes onto users of Django a dependency check and order of table creation that I believe ought to be automatically taken care of by Django. That being said, I don't think it's within my discretion to reopen this bug, and I don't know enough about Django's innards to know if a solution is either easy or obvious.
Regardless of the above, would it be possible to reopen this bug on the basis that a helpful error message is desired?
Cheers.
comment:5 by , 16 years ago
"Initializing a database" does not result in an error. The problem here is that in order to even define your model class like this, you have assumed that the ContentType
table already exists and contains records, and then you are attempting to use this definition before creating any database tables. There's no way around this: you'll need to install the tables in two steps (one to get the tables you depend on, like the one for the ContentType
model, and a second to install your applications which depend on those tables existing and being populated).
There's also no easy way to try to special-case this in Django, since you're just using the plain database API and that API (deliberately) has no way of knowing that it's being used, say, while syncdb
is being run and so should refuse to query or raise a different error message. This is really a situation where we have to trust you, the application developer, to know what you're doing and to think through the consequences of how you're setting things up.
comment:6 by , 16 years ago
Thanks for the reply, ubernostrum. I trust that the designers of Django have balanced the issues and made the right choices.
If this is an application developer issue, I believe a note in the documentation for application developers on this pre-existing database requirement of limit_choices_to would be valuable.
comment:7 by , 16 years ago
Again, this is not a "requirement" of limit_choices_to
, which works just fine. The specific problem you are encountering is solely because you have chosen to set limit_choices_to
by running a database query and it's hopefully clear that trying to run a database query before the database is set up simply can't work.
Confirmed. You can get around it by removing your custom apps from the INSTALLED_APPS first, creating the db, putting your apps back in and syncdb-ing again.