Modify

Ticket #496 (closed defect: fixed)

Opened 4 years ago

Last modified 3 years ago

Migration fails with m2m field on proxy model

Reported by: kostia.lopuhin@… Owned by: andrew
Priority: major Milestone: 0.7.2
Component: migrations Version: 0.7.1
Keywords: Cc:

Description

Migration fails then there is a ManyToMany? field referencing proxy model.
If you define models in southtest application like this:

class ModelA(models.Model):
    pass

class ProxyModel(ModelA):
    class Meta:
        proxy = True

class ModelB(models.Model):
    modela_list = models.ManyToManyField(ProxyModel)

than create initial migration, you will get the following error when trying to apply it:

kostia@kostia-laptop:~/chtd/mcxgp$ python manage.py schemamigration southtest --initial
Creating migrations directory at '/home/kostia/chtd/mcxgp/southtest/migrations'...
Creating __init__.py in '/home/kostia/chtd/mcxgp/southtest/migrations'...
 + Added model southtest.ModelA
 + Added model southtest.ModelB
 + Added M2M table for modela_list on southtest.ModelB
Created 0001_initial.py. You can now apply this migration with: ./manage.py migrate southtest

kostia@kostia-laptop:~/chtd/mcxgp$ python manage.py migrate southtest
Running migrations for southtest:
 - Migrating forwards to 0001_initial.
 > southtest:0001_initial
Traceback (most recent call last):
  File "manage.py", line 17, in <module>
    execute_manager(settings)
  File "/home/kostia/chtd/lib/django/core/management/__init__.py", line 438, in execute_manager
    utility.execute()
  File "/home/kostia/chtd/lib/django/core/management/__init__.py", line 379, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/home/kostia/chtd/lib/django/core/management/base.py", line 195, in run_from_argv
    self.execute(*args, **options.__dict__)
  File "/home/kostia/chtd/lib/django/core/management/base.py", line 222, in execute
    output = self.handle(*args, **options)
  File "/home/kostia/chtd/lib/south/management/commands/migrate.py", line 109, in handle
    ignore_ghosts = ignore_ghosts,
  File "/home/kostia/chtd/lib/south/migration/__init__.py", line 202, in migrate_app
    success = migrator.migrate_many(target, workplan, database)
  File "/home/kostia/chtd/lib/south/migration/migrators.py", line 220, in migrate_many
    result = migrator.__class__.migrate_many(migrator, target, migrations, database)
  File "/home/kostia/chtd/lib/south/migration/migrators.py", line 291, in migrate_many
    result = self.migrate(migration, database)
  File "/home/kostia/chtd/lib/south/migration/migrators.py", line 125, in migrate
    result = self.run(migration)
  File "/home/kostia/chtd/lib/south/migration/migrators.py", line 99, in run
    return self.run_migration(migration)
  File "/home/kostia/chtd/lib/south/migration/migrators.py", line 82, in run_migration
    south.db.db.execute_deferred_sql()
  File "/home/kostia/chtd/lib/south/db/generic.py", line 168, in execute_deferred_sql
    self.execute(sql)
  File "/home/kostia/chtd/lib/south/db/generic.py", line 134, in execute
    cursor.execute(sql, params)
  File "/home/kostia/chtd/lib/django/db/backends/util.py", line 20, in execute
    return self.cursor.execute(sql, params)
psycopg2.ProgrammingError: column "modela_ptr_id" referenced in foreign key constraint does not exist

using python 2.6.5, Django version 1.2 alpha 1 SVN-4476, postgresql-8.4
the problem is in generated migration, specificaly if you change this

        # Adding M2M table for field modela_list on 'ModelB'
        db.create_table('southtest_modelb_modela_list', (
            ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
            ('modelb', models.ForeignKey(orm['southtest.modelb'], null=False)),
            ('proxymodel', models.ForeignKey(orm['southtest.proxymodel'], null=False))
        ))
        db.create_unique('southtest_modelb_modela_list', ['modelb_id', 'proxymodel_id'])

to this

        # Adding M2M table for field modela_list on 'ModelB'
        db.create_table('southtest_modelb_modela_list', (
            ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
            ('modelb', models.ForeignKey(orm['southtest.modelb'], null=False)),
            ('proxymodel', models.ForeignKey(orm['southtest.modela'], null=False))
        ))
        db.create_unique('southtest_modelb_modela_list', ['modelb_id', 'proxymodel_id'])

(so that relation is with modela, not proxymodel, keeping field names the same) - than the migration runs smoothly. This workaround seems to work for me on real data.

Attachments

Change History

comment:1 Changed 4 years ago by andrew

  • Status changed from new to closed
  • Resolution set to fixed
  • Milestone set to 0.7.2

Should be fixed by [cf2413aa90cd].

View

Add a comment

Modify Ticket

Action
as closed
The resolution will be deleted. Next status will be 'reopened'
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.