#24351 closed New feature (fixed)
RunPython/RunSQL operations in contrib migrations and multi-db routers.
Reported by: | Loic Bistuer | Owned by: | nobody |
---|---|---|---|
Component: | Migrations | Version: | 1.8alpha1 |
Severity: | Normal | Keywords: | |
Cc: | Triage Stage: | Ready for checkin | |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
By default the RunPython
and RunSQL
don't give much information to the multi-db router, and before #22583 the router wasn't even consulted.
In Django 1.7 multi-db users could avoid issues by not using those operations and avoiding any 3rd party app that uses them. But in Django 1.8 the contenttypes
application adds a RunPython
operation that will fail in many multi-db setups (see commit).
To fix the immediate issue we can leverage the feature added by #22583 and provide hints to the router:
RunPython(foo, bar, hints={'app_label': 'contenttypes'})
and/or
RunPython(foo, bar, hints={'affected_models': [ContentType]})
Another option would be to make allowed_to_migrate
always provide allow_migrate
with the app_label
for the current migration.
Both options would be backwards incompatible in the same way (although the first one is constrained to people that use django.contrib.contenttypes
) because they require routers to accept the app_label
kwarg or the new **hints
syntax (see release notes).
Note that #22583 already introduced a backward incompatibility (see release notes) so people already have to update their existing routers for 1.8.
The advantage of the second option is that it'll automatically work for RunPython
and RunSQL
operations from 3rd party apps.
Change History (13)
comment:1 by , 10 years ago
Has patch: | set |
---|
comment:2 by , 10 years ago
Looking at the PR, I'm not sure we really need the app label on every allow_migrate
call. Do we? I'd rather go with hints
and put app_label
and model_name
in there. Or at least make app_label
an optional argument in which case we can use inspect.getcallargs()
to check if the respective function allows for that argument.
comment:3 by , 10 years ago
Triage Stage: | Unreviewed → Accepted |
---|
comment:4 by , 10 years ago
To summurize what I mentioned on IRC:
Every migration and operation have an app_label
but not necessarily a model
so I think it'd be unfortunate to make the former an optional keyword arg while the latter is a required positional arg.
app_label
always make sense when routing migrations, even if only as a first pass, not having it readily available requires convoluted code, see without app_label vs with app_label.
Existing routers need to be updated for Django 1.8 to handle model == None
, since any router that inspects model._meta
will blow up, so now is a good opportunity to get the API right.
inspect.getcallargs
won't work because we document calling allow_migrate
directly.
comment:5 by , 10 years ago
I've reworked the patch to allow a deprecation cycle for the old signature using inspect
; things are unsurprisingly easier when I'm not half-asleep.
Of course it's still debatable whether or not allow_migrate(self, db, app_label, model, **hints)
is the right API (I believe it is). I've started working on a ML post but it needs more work to properly lay out context and pros and cons of alternatives, I'm running out of time for today so it may have to wait for this weekend.
comment:6 by , 10 years ago
comment:7 by , 10 years ago
Type: | Uncategorized → New feature |
---|
comment:8 by , 10 years ago
Triage Stage: | Accepted → Ready for checkin |
---|
comment:9 by , 10 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
comment:11 by , 10 years ago
Severity: | Release blocker → Normal |
---|
Tentative PR https://github.com/django/django/pull/4152.