[Django] #24808: An error that occurs when 2 migrations happen to execute as the result of a single migrate command.

4 views
Skip to first unread message

Django

unread,
May 16, 2015, 1:26:37 AM5/16/15
to django-...@googlegroups.com
#24808: An error that occurs when 2 migrations happen to execute as the result of a
single migrate command.
----------------------------+------------------------
Reporter: damix911 | Owner: nobody
Type: Bug | Status: new
Component: Migrations | Version: 1.8
Severity: Normal | Keywords: migrations
Triage Stage: Unreviewed | Has patch: 0
Easy pickings: 0 | UI/UX: 0
----------------------------+------------------------
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'}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/24808>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
May 16, 2015, 1:28:17 AM5/16/15
to django-...@googlegroups.com
#24808: An error that occurs when 2 migrations happen to execute as the result of a
single migrate command.
------------------------+----------------------------

Reporter: damix911 | Owner: nobody
Type: Bug | Status: new
Component: Migrations | Version: 1.8
Severity: Normal | Resolution:

Keywords: migrations | Triage Stage: Unreviewed
Has patch: 0 | Easy pickings: 0
UI/UX: 0 |
------------------------+----------------------------
Changes (by damix911):

* Attachment "Tests.zip" added.

4 different test cases, plus the output of the one that fails.

Django

unread,
May 16, 2015, 4:59:06 AM5/16/15
to django-...@googlegroups.com
#24808: An error that occurs when 2 migrations happen to execute as the result of a
single migrate command.
----------------------------+--------------------------------------
Reporter: damix911 | Owner: nobody
Type: Bug | Status: closed
Component: Migrations | Version: 1.8
Severity: Normal | Resolution: invalid

Keywords: migrations | Triage Stage: Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
----------------------------+--------------------------------------
Changes (by claudep):

* status: new => closed
* needs_docs: => 0
* resolution: => invalid
* needs_tests: => 0
* needs_better_patch: => 0


Comment:

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.

--
Ticket URL: <https://code.djangoproject.com/ticket/24808#comment:1>

Django

unread,
May 18, 2015, 3:31:37 AM5/18/15
to django-...@googlegroups.com
#24808: An error that occurs when 2 migrations happen to execute as the result of a
single migrate command.
----------------------------+--------------------------------------
Reporter: damix911 | Owner: nobody
Type: Bug | Status: closed
Component: Migrations | Version: 1.8
Severity: Normal | Resolution: duplicate

Keywords: migrations | Triage Stage: Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
----------------------------+--------------------------------------
Changes (by MarkusH):

* resolution: invalid => duplicate


Comment:

For the record, this sounds like #24573 and has been fixed in 1.8.1 and is
properly addressed in the release notes.

--
Ticket URL: <https://code.djangoproject.com/ticket/24808#comment:2>

Reply all
Reply to author
Forward
0 new messages