#22965 closed Bug (duplicate)
InvalidBasesError for unmigrated apps subclassing contrib
| Reported by: | Collin Anderson | Owned by: | nobody |
|---|---|---|---|
| Component: | Migrations | Version: | 1.7-rc-1 |
| Severity: | Release blocker | Keywords: | |
| Cc: | cmawebsite@… | Triage Stage: | Accepted |
| Has patch: | no | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description
Unmigrated app in a project not swapping out the User model:
from django.contrib.auth.models import User
from django.db import models
class UserProfile(User):
bio = models.TextField()
syncdb and migrate give this error on latest 1.7 and master:
~/usersubclasstest$ rm db.sqlite3; PYTHONPATH=../django1.7 ./manage.py syncdb
Operations to perform:
Synchronize unmigrated apps: account
Apply all migrations: admin, contenttypes, auth, sessions
Synchronizing apps without migrations:
Creating tables...
Creating table account_userprofile
Installing custom SQL...
Installing indexes...
Running migrations:
Applying contenttypes.0001_initial...Traceback (most recent call last):
File "./manage.py", line 10, in <module>
execute_from_command_line(sys.argv)
File "/home/collin/django1.7/django/core/management/__init__.py", line 385, in execute_from_command_line
utility.execute()
File "/home/collin/django1.7/django/core/management/__init__.py", line 377, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/home/collin/django1.7/django/core/management/base.py", line 288, in run_from_argv
self.execute(*args, **options.__dict__)
File "/home/collin/django1.7/django/core/management/base.py", line 337, in execute
output = self.handle(*args, **options)
File "/home/collin/django1.7/django/core/management/base.py", line 532, in handle
return self.handle_noargs(**options)
File "/home/collin/django1.7/django/core/management/commands/syncdb.py", line 27, in handle_noargs
call_command("migrate", **options)
File "/home/collin/django1.7/django/core/management/__init__.py", line 115, in call_command
return klass.execute(*args, **defaults)
File "/home/collin/django1.7/django/core/management/base.py", line 337, in execute
output = self.handle(*args, **options)
File "/home/collin/django1.7/django/core/management/commands/migrate.py", line 160, in handle
executor.migrate(targets, plan, fake=options.get("fake", False))
File "/home/collin/django1.7/django/db/migrations/executor.py", line 62, in migrate
self.apply_migration(migration, fake=fake)
File "/home/collin/django1.7/django/db/migrations/executor.py", line 90, in apply_migration
if self.detect_soft_applied(migration):
File "/home/collin/django1.7/django/db/migrations/executor.py", line 134, in detect_soft_applied
apps = project_state.render()
File "/home/collin/django1.7/django/db/migrations/state.py", line 71, in render
raise InvalidBasesError("Cannot resolve bases for %r" % new_unrendered_models)
django.db.migrations.state.InvalidBasesError: Cannot resolve bases for [<ModelState: 'account.UserProfile'>]
Initializing the database using 1.6 syncdb doesn't help either (unless you use --fake).
I have a minimal project that reproduces the error on github.
Feel free to remove the release blocker status if what I'm doing isn't supported. If it's not supported, we should have a more helpful error message.
Change History (8)
comment:1 by , 11 years ago
| Severity: | Release blocker → Normal |
|---|---|
| Summary: | migrations break subclasses of User → better error message for unmigrated apps depending on migrated apps. |
comment:2 by , 11 years ago
| Severity: | Normal → Release blocker |
|---|---|
| Summary: | better error message for unmigrated apps depending on migrated apps. → InvalidBasesError for unmigrated apps subclassing contrib |
Marking as release blocker because someone else ran into it. https://code.djangoproject.com/ticket/22708#comment:16
comment:3 by , 11 years ago
The issue is that non migrated apps are synced before migrations happen. Could we detect the dependency and run just those migrations first? Or syncdb any depended base models and then fake their initial migrations later.
comment:4 by , 11 years ago
Or, I'm a little naive here, wouldn't it be saner to migrate first and syncdb second? It would mean you can't use migrations until your dependencies use migrations which seems fine to me (though could be a problem for non-migrated custom user models).
comment:5 by , 11 years ago
| Triage Stage: | Unreviewed → Accepted |
|---|
The same issue was also reporeted in #22922. I changed the summary there to "Add a better error messsage or an FAQ entry for InvalidBasesError" so if there's no code changes we can make here, this would be a duplicate of that.
comment:6 by , 11 years ago
| Resolution: | → duplicate |
|---|---|
| Status: | new → closed |
Yep, closing this in favour of #22922; this error is probably most caused by unmigrated depending on migrated.
Collin: If we had migrated run before syncdb, then migrated apps couldn't depend on unmigrated apps, which is much more untenable (think about all the unmigrated apps in the wild; most new apps are going to be migrated, so this way round works best). To detect dependencies we'd need to give them migrations (due to the way syncdb handles circular foreign keys) and tada, the problem has gone away anyway.
I wish we could solve this problem but I've looked into it a lot and we can't. The reason the language is "it's not advised" is because you can depend with foreign keys and suchlike fine; it's importing a base class that really blows stuff up. We should at least mention that by name, and probably call out auth specifically in the release notes as it's now migrated.
comment:8 by , 11 years ago
If it helps anyone else, I'll note that I've avoided creating migrations for my app by creating a "fake" custom user model in my app:
in myapp/models.py:
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
class Meta:
db_table = 'auth_user'
and in settings.py
AUTH_USER_MODEL = 'myapp.User'
Ahh, sure enough the release notes say "It is not advised to have apps without migrations depend on ... apps with migrations."
Seems to me we should say something stronger than "It is not advised". Maybe we should list it under "Backwards incompatible changes"? Maybe we should add a
checkor a better error message?