175👍
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.
-
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. -
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
- create your database
- add south to installed apps
- run syncdb, this will add the django and south tables to the database
- add your apps
- for each app run
python manage.py schemamigration app_name --initial
this will create the initial migration files for your app - 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
- add south to installed apps
- run syncdb, this will add the south tables to the database
- for each of your apps run
python manage.py schemamigration app_name --initial
This will create your initial migrations - 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
- create database
- add south to installed apps
- for each of your apps run
python manage.py schemamigration app_name --initial
This will create your initial migrations - run syncdb, this will add any apps that don’t have migrations to the database.
- 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.
11👍
This is how I get things working.
pip install South
# add 'south', to INSTALL_APPS, then
python manage.py syncdb
# For existing project + database
python manage.py convert_to_south app_name
# Thereafter, call them per model changes
python manage.py schemamigration app_name --auto
python manage.py migrate app_name
References:
http://garmoncheg.blogspot.com/2011/08/django-how-and-why-to-use-migrations.html
http://www.djangopro.com/2011/01/django-database-migration-tool-south-explained/
- [Django]-AWS: can't connect to RDS database from my machine
- [Django]-ImportError: cannot import name '…' from partially initialized module '…' (most likely due to a circular import)
- [Django]-Django order_by query set, ascending and descending
8👍
The tutorial you’re using states:
(If this fails complaining that
south_migrationhistory does not exist,
you forgot to run syncdb after you
installed
South.)
Assuming that your post accurately details the steps you’ve taken, following that link seems to show that you missed a step before setting up your new app. As you are following a tutorial for setting up migrations on a new application, the order is:
- Add south to
INSTALLED_APPS
. - Run
syncdb
. - Then follow the tutorial.
I.e., you should’ve already run syncdb
before you added in the models for your new app. Your solution of removing your app from INSTALLED_APPS
should work, but it’s worth noting that it’s really only a “silly” work-around, as you missed a step earlier on. Had syncdb
been run before you created the models for that app, you wouldn’t have to use the work-around.
- [Django]-How to set a Django model field's default value to a function call / callable (e.g., a date relative to the time of model object creation)
- [Django]-New url format in Django 1.9
- [Django]-Django annotation with nested filter
3👍
Just for future ref. If South is giving you any problems:
- Remove the migrations directories from your app directories
- Delete South_migrations from your database
- Run manage.py syncdb
- Go back to using South (e.g. ‘./manage.py convert_to_south something, ./manage.py migrate …’)
- [Django]-Storing an Integer Array in a Django Database
- [Django]-Django datefield filter by weekday/weekend
- [Django]-Pycharm error Django is not importable in this environment
1👍
This seems obvious, but I’d highly recommend reading the docs.
Even after reading the answers to this question I struggled to understand how to use South effectively.
That all changed of course the day I read the docs and you should too, South is simpler to use than you might think.
http://south.aeracode.org/docs/about.html
http://south.aeracode.org/docs/tutorial/index.html
http://south.aeracode.org/docs/convertinganapp.html#converting-an-app
I also found this useful:
http://www.djangopro.com/2011/01/django-database-migration-tool-south-explained/
And make sure you read Jeff Atwood’s Coding Horror articles on database version control.
- [Django]-South migration: "database backend does not accept 0 as a value for AutoField" (mysql)
- [Django]-How to stop gunicorn properly
- [Django]-How do I force Django to ignore any caches and reload data?
0👍
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.
I have used that fix with South troubles in the past. Not a pretty solution but very effective 😉
But the main problem is that your order isn’t correct. You should have run syncdb before the tutorial. Than it works properly.
- [Django]-Nginx doesn't serve static
- [Django]-Getting the SQL from a Django QuerySet
- [Django]-Django REST framework serializer without a model