professorDante
professorDante

Reputation: 2405

Resetting migrations in south leads to 'table already exists'

OK, this is driving me nuts. I'm trying to remove and reset all my south migrations in my DEV environment for two apps, and start again with a clean slate, as my migrations files list was getting very long and I don't need them, as the models are constantly changing, and it's just DEV. Whatever I try, South constantly complains that the DB tables are already there.

Going on this answer on SO, I first remove my migrations dir entirely from each app:

rm -r <my-app>/migrations

No problem. Then reset the south tables:

python manage.py reset south

Again, no worries.

Now tell south that I want those apps managed:

python manage.py convert_to_south <appname>

All seems fine, it even creates the initial migration and runs the --fake:

Created 0001_initial.py. You can now apply this migration with: ./manage.py migrate CC
- Soft matched migration 0001 to 0001_initial.
Running migrations for CC:
- Migrating forwards to 0001_initial.
> CC:0001_initial
(faked)

OK, so according to my (incorrect) understanding, I now have my existing tables managed by south. South knows that the tables ALREADY exist, as we ran initial as --fake.

Now I add a new field to a model, run schemamigration then migrate on that new schema, and guess what, South complains that the tables already exist.

django.db.utils.DatabaseError: table "_south_new_CC_coveredcall" already exists

What the hell? What on earth am I doing wrong?

Upvotes: 3

Views: 583

Answers (3)

professorDante
professorDante

Reputation: 2405

Thanks to all who contributed - it turns out that as I'm using SQlite in dev, It's this that is causing all the issues. See another question on SO for clarification. Answering my own question here as it may be useful for others - I'm switching to mySQL, as the issue I stated above doesnt exist in my PRD env, which uses mySQL. Migration all works seamlessly.

Upvotes: 0

Steve Jalim
Steve Jalim

Reputation: 12195

Caveat: it's late here and I'm tired, but it will be something along these lines:

Rather than telling South that you want to migrate an existing app (which implies a schema exists), you can fake-zero the apps, delete the migrations and make a new intitial one for each app and fake apply it. That basically gets South to replace multiple migrations with one per app

$ ./manage.py dumpdata myapp1 myapp2 > dumped.json  # just in case!
$ ./manage.py migrate myapp1 zero --fake
$ ./manage.py migrate myapp2 zero --fake
$ rm /path/to/myapp1/migrations/.py*
$ rm /path/to/myapp2/migrations/.py*
$ ./manage.py schemamigration myapp1 --initial
$ ./manage.py schemamigration myapp2 --initial
$ ./manage.py migrate myapp1 --fake 
$ ./manage.py migrate myapp2 --fake 

The new 0001 migrations for myapp1 and myapp2 will have the same result as the multiple ones that actually created the existing schema, so all will fit just fine (as long as there have been no custom SQL migrations etc)

Upvotes: 1

laidibug
laidibug

Reputation: 1219

Try this code:

rm <app>/migrations/*
python manage.py schemamigration <app> --initial
python manage.py migrate <app> 0001 --fake  --delete-ghost-migrations

Upvotes: 0

Related Questions