#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 , 10 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 , 10 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 , 10 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 , 10 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 , 10 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 , 10 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 , 10 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
check
or a better error message?