Skip to content
This repository has been archived by the owner on Feb 7, 2019. It is now read-only.

Commit

Permalink
Added a reproducing case for the VM2M migration issue described in #56
Browse files Browse the repository at this point in the history
  • Loading branch information
maennel committed Oct 17, 2015
1 parent 56ade51 commit b9b6038
Show file tree
Hide file tree
Showing 8 changed files with 144 additions and 1 deletion.
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ addons:
install:
- pip install tox
- pip install coveralls
- pip install django-migration-testcase

# Ensure PostgreSQL-DB to be configured correctly
before_script:
Expand Down
2 changes: 1 addition & 1 deletion cleanerversion/settings/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
'django.contrib.staticfiles',
'versions',
'versions_tests',
'migrations_tests',
)

MIDDLEWARE_CLASSES = (
Expand All @@ -90,4 +91,3 @@


STATIC_URL = '/static/'

Empty file added migrations_tests/__init__.py
Empty file.
53 changes: 53 additions & 0 deletions migrations_tests/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models, migrations
import versions.models


class Migration(migrations.Migration):

dependencies = [
]

operations = [
migrations.CreateModel(
name='MyMigratingModelA',
fields=[
('id', models.CharField(max_length=36, serialize=False, primary_key=True)),
('identity', models.CharField(max_length=36)),
('version_start_date', models.DateTimeField()),
('version_end_date', models.DateTimeField(default=None, null=True, blank=True)),
('version_birth_date', models.DateTimeField()),
('name', models.CharField(max_length=10)),
],
options={
'abstract': False,
},
bases=(models.Model,),
),
migrations.CreateModel(
name='MyMigratingModelB',
fields=[
('id', models.CharField(max_length=36, serialize=False, primary_key=True)),
('identity', models.CharField(max_length=36)),
('version_start_date', models.DateTimeField()),
('version_end_date', models.DateTimeField(default=None, null=True, blank=True)),
('version_birth_date', models.DateTimeField()),
('identifier', models.CharField(max_length=10)),
('a_models', versions.models.VersionedManyToManyField(to='migrations_tests.MyMigratingModelA')),
],
options={
'abstract': False,
},
bases=(models.Model,),
),
migrations.AlterUniqueTogether(
name='mymigratingmodelb',
unique_together=set([('id', 'identity')]),
),
migrations.AlterUniqueTogether(
name='mymigratingmodela',
unique_together=set([('id', 'identity')]),
),
]
Empty file.
12 changes: 12 additions & 0 deletions migrations_tests/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from django.db.models.fields import CharField
from versions.models import Versionable, VersionedManyToManyField


############################################
# MigrationTest models
class MyMigratingModelA(Versionable):
name = CharField(max_length=10)

class MyMigratingModelB(Versionable):
identifier = CharField(max_length=10)
a_models = VersionedManyToManyField('MyMigratingModelA', related_name='b_models')
Empty file.
77 changes: 77 additions & 0 deletions migrations_tests/tests/test_migrations.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import os
import re
from django.apps import apps
from django.core.management import call_command
from django.db.migrations.loader import MigrationLoader
from django_migration_testcase import MigrationTest
from django.db import migrations
import sys
import versions


class Migration(migrations.Migration):

dependencies = [
('migrations_tests', '0001_initial'),
]

operations = [
migrations.AlterField(
model_name='mymigratingmodelb',
name='a_models',
field=versions.models.VersionedManyToManyField(related_name='b_models', to='migrations_tests.MyMigratingModelA'),
preserve_default=True,
),
]

class M2MRelatedNameMigration(MigrationTest):
app = 'migrations_tests'
before = [(app, '0001_initial')]
after = []
after_migration_file = None

def call_makemigrations(self, app_name=None):
if not app_name:
app_name = self.app
try:
mig_filename_holder = "/tmp/migrations_filename.txt"
with open(mig_filename_holder, 'w') as f:
call_command('makemigrations', app_name,
verbosity=1, no_initial_data=True, stdout=f)
fh = open(mig_filename_holder, 'r')
out = fh.read().split('\n')[1]
fh.close()
match = re.match(r'.*((\d{4}_auto\w+)\.py)', out)
out_mig = match.group(2)
self.after_migration_file = "./%s/migrations/%s" % (app_name, match.group(1))
finally:
fh.close()
os.remove(mig_filename_holder)
with open(self.after_migration_file, 'r') as fh:
self.after_migration_content = fh.read()
self.after = [(app_name, out_mig)]

def tearDown(self):
try:
os.remove(self.after_migration_file)
except Exception as e:
print str(e)
super(M2MRelatedNameMigration, self).tearDown()

def test_migration(self):
MyMigratingModelA = self.get_model_before('migrations_tests.MyMigratingModelA')
MyMigratingModelB = self.get_model_before('migrations_tests.MyMigratingModelB')

self.assertIn('mymigratingmodelb_set', MyMigratingModelA.__dict__)

# Make migration file
self.call_makemigrations()
print "----------\n%s\n----------\n" % self.after_migration_content

# self.run_migration runs the newly created migration and thus provokes an error:
# "AttributeError: 'VersionedManyToManyField' object has no attribute '_m2m_reverse_name_cache'"
self.assertRaises(AttributeError, self.run_migration)

# MyMigratingModelA = self.get_model_after('migrations_tests.MyMigratingModelA')
# MyMigratingModelB = self.get_model_after('migrations_tests.MyMigratingModelB')
# self.assertIn('b_models', MyMigratingModelA.__dict__)

0 comments on commit b9b6038

Please sign in to comment.