South won't generate or apply migrations for existing app, with changes to migrate
I'm using South to generate and apply migrations, rather than managing that myself. Unfortunately, South is refusing to actually do anything. Transcript below:
[graffias:~/testing.tustincommercial.com/oneclickcos]$ python ./manage.py schemamigration mainapp --auto
You cannot use --auto on an app with no migrations. Try --initial.
[graffias:~/testing.tustincommercial.com/oneclickcos]$ python ./manage.py schemamigration mainapp --initial
+ Added model mainapp.CompanyUK
+ Added model mainapp.CompanyName
+ Added model mainapp.Individual
+ Added model mainapp.Director
+ Added model mainapp.DirectorsIndividual
+ Added model mainapp.DirectorsCorporate
+ Added model mainapp.ShareCapitalClass
+ Added model mainapp.Member
+ Added model mainapp.MembersIndividual
+ Added model mainapp.MemberGener开发者_如何学运维ic
+ Added model mainapp.CompanyManager
+ Added model mainapp.PendingRegistration
+ Added model mainapp.PendingAuthorisation
Created 0001_initial.py. You can now apply this migration with: ./manage.py migrate mainapp
[graffias:~/testing.tustincommercial.com/oneclickcos]$ python ./manage.py migrate mainapp
Running migrations for mainapp:
- Nothing to migrate.
- Loading initial data for mainapp.
No fixtures found.
[graffias:~/testing.tustincommercial.com/oneclickcos]$
As you can see, South thinks there is nothing to do. However, the last three models are completely new, and have no table in the database.
Is there anything I can do, short of zapping the database to get South working again?
I have no intention of manually writing migrations for the rest of the project, but if it would help, I would write one migration.
I guess you got yourself in trouble by not starting out with ./manage.py convert_to_south mainapp
. Maybe you can correct this by doing :
(1) Make South believe you didn't perform the first migration, so go to zero
./manage.py migrate --fake mainapp zero
(2) Migrate for real to the first migration.
./manage.py migrate mainapp
But for what I can make of your question you already had some models in your database made without South, otherwise you wouldn't have had to use --initial
. If so it will probably complain about columns already existing.
You can change this situation by :
(1) Wiping out the first schemamigration by deleting mainapp/migrations/0001_initial.py. You don't need to fiddle with the South database table directly, --delete-ghost-migrations
will take care of this.
(2) ./manage.py syncdb
South expects the database to be in sync with the models.
(3) ./manage.py convert_to_south mainapp
to actually let South handle the database and the migrations.
(4) ./manage.py migrate --delete-ghost-migrations mainapp
to move to the first migration and deleting the old first migration you deleted from migrations/ from the database
From the department of dirty hacks:
This process solved my problem, but it is hardly elegant.
(1) Remove all migrations in the affected app (rm mainapp/migrations/*
)
(2) Remove your models.py, and replace it with an empty file (mv mainapp/models.py .; rm mainapp/*.pyc; touch mainapp/models.py
)
(3) Generate an initial migration that does nothing (python ./manage.py schemamigration mainapp --initial
), and apply it (python ./manage.py migrate mainapp
)
(4) Restore ones models, and generate a migration which which will recreate everything (rm mainapp/models.py; mv models.py mainapp/; python ./manage.py schemamigration mainapp --auto
)
(5) BEFORE running the new migration, edit it to comment out all the changes that are not really new changes. Alternatively, run it, and have it fail on the tables that actually exist, then comment out everything.
(6) Apply your migration to put south into something like a normal state (and perform your changes if you followed my recommended course in step (5): python ./manage.py migrate mainapp
)
Better and cleaner suggestions are welcome, as are any indications of what else this approach might break.
Also note that, if you are using QuerySet cache like Johnny Cache, deleting migration history from database won't help, you need to either kill memcached: killall memcached
or for projects in production you need to invalidate south_migrationhistory table using following using python manage.py shell
:
from johnny.cache import invalidate
invalidate('south_migrationhistory')
That was the case for me.
If you've already created a database, then you need to use:
python manage.py convert_to_south myapp
instead of schemamigration. If it's too late for that, and you don't care about the data in your database run:
- clear database with:
python manage.py flush
- delete old migrations with:
sudo rm /path/to/myapp/migrations/*.*
python manage.py syncdb
sudo python manage.py convert_to_south myapp
精彩评论