#22002 closed Cleanup/optimization (fixed)
AppConfig.ready() and tests
Reported by: | Marc Tamlyn | Owned by: | Zbigniew Siciarz |
---|---|---|---|
Component: | Documentation | Version: | dev |
Severity: | Release blocker | Keywords: | app-loading |
Cc: | Triage Stage: | Accepted | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
If you do something with the database in AppConfig.ready(), then during test runs it runs against the production db as it happens before django knows it's testing. I don't think there's any way to change this, but it should be documented.
Change History (9)
comment:1 by , 11 years ago
comment:2 by , 11 years ago
Keywords: | app-loading added |
---|
comment:3 by , 11 years ago
I think it is somewhat dangerous that stuff can get executed against the production database (even though the test config shouldn't have it in settings at all). Can't we (re)configure the databases earlier?
comment:4 by , 11 years ago
I discovered this accidentally investigating (bad) solutions for #22022. I propose just docs. At the moment, manage.py test
is not special cased in the core management. We call django.setup()
and then branch on the command used. I think that we should:
1) recommend never interacting with the database in ready()
(or in startup code in general - this is what migrations are for right?)
2) mention that it would be run against the main database even in testing
I don't think it's actually that big a deal about the test/prod situation. Such code would be run *every time* you call a management command of any kind, so you'd soon find out if you were breaking the db. We could theoretically explicitly error during the calls to ready()
if we try to obtain a connection cursor, but that would be a bit dirty in its implementation.
comment:5 by , 11 years ago
Owner: | changed from | to
---|---|
Status: | new → assigned |
comment:6 by , 11 years ago
I added mjtamlyn's suggestions to AppConfig docs as a warning note. Relevant PR: https://github.com/django/django/pull/2294
comment:7 by , 11 years ago
Resolution: | → fixed |
---|---|
Status: | assigned → closed |
comment:8 by , 11 years ago
If it's not terribly difficult to implement then I'd like to advocate the "explicit error" way of solving this issue. These kind of things are easily overseen and difficult to debug and/or can cause severe damage in your database. (People will abuse the ready()
method for all kinds of things you'd never dream about...)
comment:9 by , 11 years ago
The real solution is to stop pretending it's a good design to switch to a different database magically for tests... Tests should run with the database specified in the settings, and Django should require specific settings for tests...
Is there a use case driving this? I'm having difficulty thinking of any sort of database activity that you would need to do in a ready() method. Of course, that's probably due to a lack of imagination on my part.
Agreed that at the very least, there needs to be docs, even if those docs are "don't do that".