See
https://groups.google.com/forum/#!topic/django-developers/2DzLBbk8w-w
This ticket is for resolving the current issue in 1.9. I also want to
write a test or two to prevent this issue from happening in the future.
--
Ticket URL: <https://code.djangoproject.com/ticket/26401>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
* owner: nobody => satchamo
* status: new => assigned
* needs_docs: => 0
* needs_tests: => 0
* needs_better_patch: => 0
--
Ticket URL: <https://code.djangoproject.com/ticket/26401#comment:1>
* stage: Unreviewed => Accepted
--
Ticket URL: <https://code.djangoproject.com/ticket/26401#comment:2>
* has_patch: 0 => 1
Comment:
https://github.com/django/django/pull/6420
--
Ticket URL: <https://code.djangoproject.com/ticket/26401#comment:3>
* needs_tests: 0 => 1
--
Ticket URL: <https://code.djangoproject.com/ticket/26401#comment:4>
* status: assigned => new
* owner: satchamo =>
Comment:
De-assigning so it's clear this is available for a PyCon sprinter to
finish up with tests.
--
Ticket URL: <https://code.djangoproject.com/ticket/26401#comment:5>
* owner: => andkon
* status: new => assigned
--
Ticket URL: <https://code.djangoproject.com/ticket/26401#comment:6>
Comment (by satchamo):
Another patch attempt: https://github.com/django/django/pull/6779
--
Ticket URL: <https://code.djangoproject.com/ticket/26401#comment:7>
Comment (by aaugustin):
FWIW I don't see a lot of value in adding this constraint. Implementing it
requires a fragile and untestable combination of inner imports to avoid
touching the models module.
If the only problem is to avoid creating tables in the database, add a
`MIGRATION_MODULES` entry for the auth app that points to an empty
package. I never tried it but I think it should work.
If this workaround is confirmed to work, I propose to close this ticket as
wontfix.
--
Ticket URL: <https://code.djangoproject.com/ticket/26401#comment:8>
Comment (by satchamo):
Interesting idea. It works:
{{{
MIGRATION_MODULES = {
'auth': None
}
}}}
My complaint was driven by the unnecessary clutter in my database when
using a custom user model. So now that there is a reasonable solution, I'm
fine with closing this.
--
Ticket URL: <https://code.djangoproject.com/ticket/26401#comment:9>
* status: assigned => closed
* resolution: => wontfix
--
Ticket URL: <https://code.djangoproject.com/ticket/26401#comment:10>
Comment (by aaugustin):
Great! Thanks for reporting back.
--
Ticket URL: <https://code.djangoproject.com/ticket/26401#comment:11>
Comment (by jdufresne):
I found the above to be insufficient. Adding `MIGRATION_MODULES` as the
only change to avoid the auth tables fails during migrations with the
following trace:
{{{
Traceback (most recent call last):
File ".../manage.py", line 9, in <module>
execute_from_command_line(sys.argv)
File ".../venv/lib64/python3.5/site-
packages/django/core/management/__init__.py", line 367, in
execute_from_command_line
utility.execute()
File ".../venv/lib64/python3.5/site-
packages/django/core/management/__init__.py", line 359, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File ".../venv/lib64/python3.5/site-
packages/django/core/management/base.py", line 305, in run_from_argv
self.execute(*args, **cmd_options)
File ".../venv/lib64/python3.5/site-
packages/django/core/management/base.py", line 356, in execute
output = self.handle(*args, **options)
File ".../venv/lib64/python3.5/site-
packages/django/core/management/commands/migrate.py", line 222, in handle
self.verbosity, self.interactive, connection.alias,
apps=post_migrate_apps, plan=plan,
File ".../venv/lib64/python3.5/site-
packages/django/core/management/sql.py", line 53, in
emit_post_migrate_signal
**kwargs
File ".../venv/lib64/python3.5/site-
packages/django/dispatch/dispatcher.py", line 191, in send
response = receiver(signal=self, sender=sender, **named)
File ".../venv/lib64/python3.5/site-
packages/django/contrib/auth/management/__init__.py", line 75, in
create_permissions
"content_type", "codename"
File ".../venv/lib64/python3.5/site-packages/django/db/models/query.py",
line 256, in __iter__
self._fetch_all()
File ".../venv/lib64/python3.5/site-packages/django/db/models/query.py",
line 1085, in _fetch_all
self._result_cache = list(self.iterator())
File ".../venv/lib64/python3.5/site-packages/django/db/models/query.py",
line 125, in __iter__
for row in compiler.results_iter():
File ".../venv/lib64/python3.5/site-
packages/django/db/models/sql/compiler.py", line 789, in results_iter
results = self.execute_sql(MULTI)
File ".../venv/lib64/python3.5/site-
packages/django/db/models/sql/compiler.py", line 835, in execute_sql
cursor.execute(sql, params)
File ".../venv/lib64/python3.5/site-
packages/django/db/backends/utils.py", line 79, in execute
return super(CursorDebugWrapper, self).execute(sql, params)
File ".../venv/lib64/python3.5/site-
packages/django/db/backends/utils.py", line 64, in execute
return self.cursor.execute(sql, params)
File ".../venv/lib64/python3.5/site-packages/django/db/utils.py", line
94, in __exit__
six.reraise(dj_exc_type, dj_exc_value, traceback)
File ".../venv/lib64/python3.5/site-packages/django/utils/six.py", line
685, in reraise
raise value.with_traceback(tb)
File ".../venv/lib64/python3.5/site-
packages/django/db/backends/utils.py", line 64, in execute
return self.cursor.execute(sql, params)
django.db.utils.ProgrammingError: relation "auth_permission" does not
exist
LINE 1: ...ntent_type_id", "auth_permission"."codename" FROM "auth_perm...
}}}
This fails becuase the auth's `AppConfig`
[https://github.com/django/django/blob/38cf9ef390eb0cd0703d99893f826153865f6ba6/django/contrib/auth/apps.py#L15-L18
adds a post_migrate callback] that requires the `auth_permission` table to
exist. A project could avoid this by overriding the auth's `AppConfig`. I
think this could be easier for projects if the auth's `AppConfig` was
split into two classes, one base version that can be used without the auth
tables and one that matches the current implementation. This would be a
backwards compatible change that would allow the `MIGRATION_MODULES`
change noted above. For example:
{{{
class BaseAuthConfig(AppConfig):
name = 'django.contrib.auth'
verbose_name = _("Authentication and Authorization")
def ready(self):
checks.register(check_user_model, checks.Tags.models)
class AuthConfig(BaseAuthConfig):
def ready(self):
post_migrate.connect(
create_permissions,
dispatch_uid="django.contrib.auth.management.create_permissions"
)
checks.register(check_models_permissions, checks.Tags.models)
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/26401#comment:12>
* status: closed => new
* resolution: wontfix =>
--
Ticket URL: <https://code.djangoproject.com/ticket/26401#comment:13>
Comment (by jdufresne):
[https://github.com/django/django/pull/7188 PR] implementing the
`AppConfig`s described above.
Not sure how to best add a test for this though. Looking for advice.
Details in the PR.
--
Ticket URL: <https://code.djangoproject.com/ticket/26401#comment:14>
* needs_tests: 1 => 0
Comment:
A test has been added to the PR above.
--
Ticket URL: <https://code.djangoproject.com/ticket/26401#comment:15>
* needs_better_patch: 0 => 1
* easy: 1 => 0
--
Ticket URL: <https://code.djangoproject.com/ticket/26401#comment:16>
* needs_better_patch: 1 => 0
* stage: Accepted => Ready for checkin
--
Ticket URL: <https://code.djangoproject.com/ticket/26401#comment:17>
* status: new => closed
* resolution: => fixed
Comment:
In [changeset:"1ec1633cb294d8ce2a65ece6b56c258483596fba" 1ec1633c]:
{{{
#!CommitTicketReference repository=""
revision="1ec1633cb294d8ce2a65ece6b56c258483596fba"
Fixed #26401 -- Added BaseAuthConfig to use auth without migrations.
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/26401#comment:18>
Comment (by Jon Dufresne):
I've hit another snag with the `MIGRATION_MODULES = {'auth': None}`
approach. (Sorry, is it better to reopen this ticket or file a new one?)
The `auth.Permission` model has a fk on `ContentType`. Due to this, when
deleting a `ContentType` (such as with the `remove_stale_contenttypes`
command) queries against the missing `auth_permission` table can occur.
Not sure how best to handle this scenario. IIUC, as long as auth is in
`INSTALLED_APPS`, the models will be loaded and this FK will cause an
issue.
Here is a stack trace when deleting a stale content type
{{{
Traceback (most recent call last):
File "/usr/lib64/python3.5/runpy.py", line 170, in _run_module_as_main
"__main__", mod_spec)
File "/usr/lib64/python3.5/runpy.py", line 85, in _run_code
exec(code, run_globals)
File "/home/jon/devel/django/django/__main__.py", line 9, in <module>
management.execute_from_command_line()
File "/home/jon/devel/django/django/core/management/__init__.py", line
366, in execute_from_command_line
utility.execute()
File "/home/jon/devel/django/django/core/management/__init__.py", line
358, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/home/jon/devel/django/django/core/management/base.py", line 294,
in run_from_argv
self.execute(*args, **cmd_options)
File "/home/jon/devel/django/django/core/management/base.py", line 345,
in execute
output = self.handle(*args, **options)
File
"/home/jon/devel/django/django/contrib/contenttypes/management/commands/remove_stale_contenttypes.py",
line 46, in handle
collector.collect([ct])
File "/home/jon/devel/django/django/db/models/deletion.py", line 218, in
collect
elif sub_objs:
File "/home/jon/devel/django/django/db/models/query.py", line 260, in
__bool__
self._fetch_all()
File "/home/jon/devel/django/django/db/models/query.py", line 1072, in
_fetch_all
self._result_cache = list(self.iterator())
File "/home/jon/devel/django/django/db/models/query.py", line 54, in
__iter__
results = compiler.execute_sql()
File "/home/jon/devel/django/django/db/models/sql/compiler.py", line
847, in execute_sql
cursor.execute(sql, params)
File "/home/jon/devel/django/django/db/backends/utils.py", line 64, in
execute
return self.cursor.execute(sql, params)
File "/home/jon/devel/django/django/db/utils.py", line 94, in __exit__
six.reraise(dj_exc_type, dj_exc_value, traceback)
File "/home/jon/devel/django/django/utils/six.py", line 685, in reraise
raise value.with_traceback(tb)
File "/home/jon/devel/django/django/db/backends/utils.py", line 64, in
execute
return self.cursor.execute(sql, params)
File "/home/jon/devel/django/django/db/backends/sqlite3/base.py", line
334, in execute
return Database.Cursor.execute(self, query, params)
django.db.utils.OperationalError: no such table: auth_permission
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/26401#comment:19>
* Attachment "ticket-26401-remove-stale-contenttypes.patch" added.
Test case for remove_stale_contenttypes with auth migrations disabled
* keywords: auth => auth 1.11
* has_patch: 1 => 0
* type: Bug => New feature
* stage: Ready for checkin => Accepted
Comment:
It's appropriate to reopen a ticket if the fix hasn't been released yet.
--
Ticket URL: <https://code.djangoproject.com/ticket/26401#comment:20>
* status: closed => new
* resolution: fixed =>
Comment:
Reopening until the above issue is handled.
--
Ticket URL: <https://code.djangoproject.com/ticket/26401#comment:21>
* has_patch: 0 => 1
Comment:
I'm unable to think of a sensible solution to the `ContentType`
`auth.Permission` dependency issue. Therefore, I'm suggesting to revert my
previous PR as using auth without migrations will not fully work.
[https://github.com/django/django/pull/7410 PR to revert]
--
Ticket URL: <https://code.djangoproject.com/ticket/26401#comment:22>
Comment (by Tim Graham):
It seems like you basically want an
`apps.register.Apps.unregister_model()` method or some way of telling
Django not to setup relations for a given model. This might not be
trivial, so if you want to revert for now, that's fine with me.
--
Ticket URL: <https://code.djangoproject.com/ticket/26401#comment:23>
* status: new => closed
* resolution: => fixed
Comment:
In [changeset:"f3ea0c4bbd5fa9bac73049839ce5de388d53371a" f3ea0c4]:
{{{
#!CommitTicketReference repository=""
revision="f3ea0c4bbd5fa9bac73049839ce5de388d53371a"
Reverted "Fixed #26401 -- Added BaseAuthConfig to use auth without
migrations."
This reverts commit 1ec1633cb294d8ce2a65ece6b56c258483596fba as it
doesn't handle ContentType's auth.Permission dependency. Thus, it
doesn't allow auth without migrations.
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/26401#comment:24>
* status: closed => new
* resolution: fixed =>
Comment:
Reopening. The revert commit was merged.
--
Ticket URL: <https://code.djangoproject.com/ticket/26401#comment:25>
* keywords: auth 1.11 => auth
* has_patch: 1 => 0
--
Ticket URL: <https://code.djangoproject.com/ticket/26401#comment:26>
* owner: Andrew Konoff => (none)
* status: new => assigned
--
Ticket URL: <https://code.djangoproject.com/ticket/26401#comment:27>
* status: assigned => new
--
Ticket URL: <https://code.djangoproject.com/ticket/26401#comment:28>