Why don't my south migrations work?

TIMEX picture TIMEX · Jan 30, 2011 · Viewed 48.2k times · Source

First, I create my database.

create database mydb;

I add "south" to installed Apps. Then, I go to this tutorial: http://south.aeracode.org/docs/tutorial/part1.html

The tutorial tells me to do this:

$ py manage.py  schemamigration wall --initial
>>> Created 0001_initial.py. You can now apply this migration with: ./manage.py migrate wall

Great, now I migrate.

$ py manage.py migrate wall

But it gives me this error...

django.db.utils.DatabaseError: (1146, "Table 'fable.south_migrationhistory' doesn't exist")

So I use Google (which never works. hence my 870 questions asked on Stackoverflow), and I get this page: http://groups.google.com/group/south-users/browse_thread/thread/d4c83f821dd2ca1c

Alright, so I follow that instructions

>> Drop database mydb;
>> Create database mydb;
$ rm -rf ./wall/migrations
$ py manage.py syncdb

But when I run syncdb, Django creates a bunch of tables. Yes, it creates the south_migrationhistory table, but it also creates my app's tables.

Synced:
 > django.contrib.admin
 > django.contrib.auth
 > django.contrib.contenttypes
 > django.contrib.sessions
 > django.contrib.sites
 > django.contrib.messages
 > south
 > fable.notification
 > pagination
 > timezones
 > fable.wall
 > mediasync
 > staticfiles
 > debug_toolbar

Not synced (use migrations):
 - 
(use ./manage.py migrate to migrate these)

Cool....now it tells me to migrate these. So, I do this:

$ py manage.py  migrate wall
The app 'wall' does not appear to use migrations.

Alright, so fine. I'll add wall to initial migrations.

$ py manage.py schemamigration wall --initial

Then I migrate:

$ py manage.py migrate wall

You know what? It gives me this BS:

_mysql_exceptions.OperationalError: (1050, "Table 'wall_content' already exists")

Sorry, this is really pissing me off. Can someone help ? thanks.

How do I get South to work and sync correctly with everything? The only thing I can think of is remove my app from INSTALLED_APPS, then run syncdb, then add it back on.

That is SO SILLY.

Answer

Ken Cochrane picture Ken Cochrane · Jan 30, 2011

South allows you to create migrations when you first start out with a new app and the tables haven't been added to the database yet, as well as creating migrations for legacy apps that already have tables in the database. The key is to know when to do what.

Your first mistake was when you deleted your migrations, as soon as you did that, and then ran syncdb, Django didn't know that you wanted south to manage that app anymore, so it created the tables for you. When you created your initial migrations and then ran migrate, south was trying to create tables that django already created, and thus your error.

At this point you have two options.

  1. Delete the tables for the wall app from your database and then run $ py manage.py migrate wall This will run the migration and create your tables.

  2. Fake out the initial migration run $ py manage.py migrate wall 0001 --fake This will tell south that you already have the tables on the database so just fake it, which will add a row to the south_migrationhistory table, so that the next time you run a migrate it will know that the first migration has already been run.

Setting up a brand new project and no database

  1. create your database
  2. add south to installed apps
  3. run syncdb, this will add the django and south tables to the database
  4. add your apps
  5. for each app run python manage.py schemamigration app_name --initial this will create the initial migration files for your app
  6. then run south migrate python manage.py migrate app_name this will add the tables to the database.

Setting up a legacy project and database

  1. add south to installed apps
  2. run syncdb, this will add the south tables to the database
  3. for each of your apps run python manage.py schemamigration app_name --initial This will create your initial migrations
  4. for each of your apps run python manage.py migrate app_name 0001 --fake , this will fake out south, it won't do anything to the database for those models, it will just add records to the south_migrationhistory table so that the next time you want to create a migration, you are all set.

Setting up a legacy project and no database

  1. create database
  2. add south to installed apps
  3. for each of your apps run python manage.py schemamigration app_name --initial This will create your initial migrations
  4. run syncdb, this will add any apps that don't have migrations to the database.
  5. then run south migrate python manage.py migrate this will run all migrations for your apps.

Now that you are setup with south, you can start using south to manage model changes to those apps. The most common command to run is python manage.py schemamigration app_name migration_name --auto that will look at the last migration you ran and it will find the changes and build out a migration file for you. Then you just need to run python manage.py migrate and it alter your database for you.

Hope that helps.