#24808 closed Bug (duplicate)
An error that occurs when 2 migrations happen to execute as the result of a single migrate command.
Reported by: | damix911 | Owned by: | nobody |
---|---|---|---|
Component: | Migrations | Version: | 1.8 |
Severity: | Normal | Keywords: | migrations |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
I'm using Python 3.4.2 and Django 1.8 and 1.8.1. The problem systematically occurs only with Django 1.8 but the 1.8.1 (or 1.8.2) release notes don't mention the presence of such a bug so I think I should describe my experience to the community anyway.
models.py:
from django.db import models class Parent(models.Model): pass class RelatedA(models.Model): parent = models.ForeignKey('Parent') class RelatedB(models.Model): parent = models.ForeignKey('Parent')
A custom data migration 0002_populate.py used to populate the DB with some initial data:
# -*- coding: utf-8 -*- from __future__ import unicode_literals from django.db import models, migrations def populate(apps, schema_editor): Parent = apps.get_model("foo", "Parent") if not Parent.objects.filter().exists(): p = Parent() p.save() RelatedX = apps.get_model("foo", <<<either "RelatedA" or "RelatedB">>>) if not RelatedX.objects.filter(parent = p).exists(): print("\n ********** :-) :-) :-) **********\n") class Migration(migrations.Migration): dependencies = [ ('foo', '0001_initial'), ] operations = [ migrations.RunPython(populate) ]
Line 13 of the data migration has been tested like this:
RelatedX = apps.get_model("foo", "RelatedA")
And like this:
RelatedX = apps.get_model("foo", "RelatedB")
In Django 1.8 and 1.8.1; this gives rise to 4 different tests:
- proj180a: Uses Django 1.8 and imports "RelatedA"
- proj180b: Uses Django 1.8 and imports "RelatedB"
- proj181a: Uses Django 1.8.1 and imports "RelatedA"
- proj181b: Uses Django 1.8.1 and imports "RelatedB"
The test involves running the command:
python manage.py migrate
When the SQLite database still doesn't exist.
The results are as follows:
- proj180a: Fails on first run, succeeds if
python manage.py migrate
is run again. - proj180b: Pass.
- proj181a: Pass.
- proj181b: Pass.
The failure of proj180a is as follows:
File "C:\Users\dario\Desktop\Repos\Programming\Django\Varie\venv-34-180\lib\site-packages\django\db\models\sql\query.py", line 1170, in build_filter self.check_related_objects(field, value, opts) File "C:\Users\dario\Desktop\Repos\Programming\Django\Varie\venv-34-180\lib\site-packages\django\db\models\sql\query.py", line 1068, in check_related_objects self.check_query_object_type(value, opts) File "C:\Users\dario\Desktop\Repos\Programming\Django\Varie\venv-34-180\lib\site-packages\django\db\models\sql\query.py", line 1052, in check_query_object_type (value, opts.object_name)) ValueError: Cannot query "Parent object": Must be "Parent" instance.
If the DB exists and migration 0001_initial.py has already been applied then also the proj180a test passes on the first run. I'm attaching the full output (obviously with stderr included) of three consecutive runs of migrate
.
In synthesis, there seems to be a problem with chaining migrations in a single migrate command (which should be a fairly typical case). Why this happens with RelatedA
and not with RelatedB
is beyond me, but must have something to do with the order in which the models are declared in models.py.
I'm attaching an archive with four projects; two for Django 1.8 and two for Django 1.8.1. To reproduce the issue you should use a virtualenv with Diango 1.8 to migrate
proj180a and proj180b and a virtualenv with Django 1.8.1 to migrate
proj181a and proj181b.
Finally, I should mention that I derived the discussed SSCCEs from the code of a real application I'm working on.
In my application the role of Parent
and RelatedA
is played by Organization
and Link
(my application is a CMS that can serve multiple independent organizations, and specifically each one of them can mantain its own set of links to other resources and pages).
In the real thing, the line that causes problems is:
if not Link.objects.filter(organization = organization, slug = slug).exists():
Which results in the following error (like proj180a) on the first migrate
run.
ValueError: Cannot query "Organization object": Must be "Organization" instance.
It is interesting to note that using related managers doesn't solve the issue (actually, I discovered the bug while using RMs, but then I learned that RMs can create problems in migrations, so I opted for the joint condition filter).
However the error message is not the same, and also in this case the second migrate
runs fine.
if not organization.link_set.filter(slug = slug).exists():
Results in:
AttributeError: 'Organization' object has no attribute 'link_set'
Attachments (1)
Change History (3)
by , 9 years ago
comment:1 by , 9 years ago
Resolution: | → invalid |
---|---|
Status: | new → closed |
Should we assume from your report that the problem cannot be reproduced on Django 1.8.1? If it's the case, then why bother? Sorry if I misunderstood the issue.
comment:2 by , 9 years ago
Resolution: | invalid → duplicate |
---|
For the record, this sounds like #24573 and has been fixed in 1.8.1 and is properly addressed in the release notes.
4 different test cases, plus the output of the one that fails.