Migration `link:0003_page_link` fails on InnoDB #1427

Closed
Bouke opened this Issue Sep 18, 2012 · 6 comments

Comments

Projects
None yet
4 participants
Contributor

Bouke commented Sep 18, 2012

When trying to deploy my site with Django-cms; it failed on the initial phase of creating the database. Migration link:0003_page_link tries to rename a column, which fails on InnoDB because of foreign key constraints.

Stack trace:

$bin/python app/manage.py migrate
Running migrations for cms:
 - Migrating forwards to 0035_auto__add_field_globalpagepermission_can_view__add_field_pagepermissio.
 > cms:0001_initial
 > cms:0002_auto_start
 > cms:0003_remove_placeholder
 > cms:0004_textobjects
 > cms:0005_mptt_added_to_plugins
 > text:0001_initial
 > text:0002_freeze
 > cms:0006_apphook
 > cms:0007_apphook_longer
 > cms:0008_redirects
 > cms:0009_added_meta_fields
 > cms:0010_5char_language
 > cms:0011_title_overwrites
 > cms:0012_publisher
 > text:0003_publisher
 > picture:0001_initial
 > picture:0002_link_rename
 > picture:0003_freeze
 > picture:0004_publisher
 > link:0001_initial
 > link:0002_link_rename
 > link:0003_page_link
 ! Error found during real run of migration! Aborting.

 ! Since you have a database that does not support running
 ! schema-altering statements in transactions, we have had 
 ! to leave it in an interim state between migrations.

! You *might* be able to recover with:
 ! The South developers regret this has happened, and would
 ! like to gently persuade you to consider a slightly
 ! easier-to-deal-with DBMS.
 ! NOTE: The error which caused the migration to fail is further up.
Traceback (most recent call last):
  File "app/manage.py", line 23, in <module>
    utility.execute()
  File "./site-packages/django/core/management/__init__.py", line 379, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "./site-packages/django/core/management/base.py", line 191, in run_from_argv
    self.execute(*args, **options.__dict__)
  File "./site-packages/django/core/management/base.py", line 220, in execute
    output = self.handle(*args, **options)
  File "./site-packages/south/management/commands/migrate.py", line 105, in handle
    ignore_ghosts = ignore_ghosts,
  File "./site-packages/south/migration/__init__.py", line 191, in migrate_app
    success = migrator.migrate_many(target, workplan, database)
  File "./site-packages/south/migration/migrators.py", line 221, in migrate_many
    result = migrator.__class__.migrate_many(migrator, target, migrations, database)
  File "./site-packages/south/migration/migrators.py", line 292, in migrate_many
    result = self.migrate(migration, database)
  File "./site-packages/south/migration/migrators.py", line 125, in migrate
    result = self.run(migration)
  File "./site-packages/south/migration/migrators.py", line 99, in run
    return self.run_migration(migration)
  File "./site-packages/south/migration/migrators.py", line 81, in run_migration
    migration_function()
  File "./site-packages/south/migration/migrators.py", line 57, in <lambda>
    return (lambda: direction(orm))
  File "./site-packages/cms/plugins/link/migrations/0003_page_link.py", line 9, in forwards
    db.rename_column("link_link", "page_id", "page_link_id")
  File "./site-packages/south/db/mysql.py", line 71, in rename_column
    self.execute(sql)
  File "./site-packages/south/db/generic.py", line 150, in execute
    cursor.execute(sql, params)
  File "./site-packages/django/db/backends/mysql/base.py", line 86, in execute
    return self.cursor.execute(query, args)
  File "./site-packages/MySQLdb/cursors.py", line 174, in execute
    self.errorhandler(self, exc, value)
  File "./site-packages/MySQLdb/connections.py", line 36, in defaulterrorhandler
    raise errorclass, errorvalue
_mysql_exceptions.OperationalError: (1025, "Error on rename of './project/#sql-3fd2_68' to './project/link_link' (errno: 150)")

Offending migration:

def forwards(self, orm):
    db.rename_column("link_link", "page_id", "page_link_id")

Possible solution: removing foreign key first, re-adding it later on.

Contributor

yakky commented Sep 18, 2012

Old django-cms migrations have issues with recent (>0.7.3) South versions.
As suggested in the tutorial (http://django-cms.readthedocs.org/en/2.3.1/getting_started/tutorial.html#fresh-install), use syncdb --all / migrate --fake to overcome this issue

Contributor

Bouke commented Sep 18, 2012

It is not a real solution, this completely ruins auto-deployments. Also, it is very annoying to do when django-cms is combined with (custom) applications in need of real migrations.

The number of users installing a clean system (with migrations) is probably larger than the total number of users wanting to upgrade from such very old versions. To better serve the larger userbase, it would be best to combine all these old migrations into a new initial version. Say for the plugin link migrations 0001-0005 will be combined into a new initial 0001 and migrations 0002-0005 are replaced with dummy migrations (to remain compatible).

Member

digi604 commented Sep 19, 2012

I like the suggestion from @Bouke. Would accept a pull request.

Contributor

yakky commented Sep 19, 2012

I guess this is targeted to 2.4
Actually I should have something in the stash: there are many migration related opened issues and I toyed with the idea to fix them by rewriting migrations
More on this later

Contributor

yakky commented Sep 19, 2012

What would a proper test strategy would be for this?
Testsuite isn't of any help here
Is running syncdb / migrate --all on different dbms enough?

Member

digi604 commented Sep 19, 2012

should be. Would be nice if we could automate it so they don't break in the future.

czpython closed this May 27, 2013

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment