Botched Migration: Table already deleted - django

I'm not sure what went wrong, but I have a migration to remove a model (database table). The table has been removed, but South does not think the migration has been applied, so when I migrate it tries to remove it, and fails, halting further migrations.
What should I do?

All you need to do to fix this kind of inconsistency is run the migration with --fake:
./manage.py migrate app --fake
From the docs:
--fake: Records the migration sequence as having been applied, but doesn’t actually run it. Useful for Converting An App.

Related

Delete Heroku migrations

I read advices how to delete migrations but I don't understand what I'm doing and it's not working for me.
History. One day I had an issue when I added or renamed a model fields locally. So I was tired with that issue and I deleted all migrations and migrate again. And all was OK. But I remember that I will have a big problem when I will deploy on Heroku.
So the days are gone. And now it happened. :(((
I make migrations, migrate to a server database. Pushed my code, but.. it wrote me:
relation "accounts_goal" does not exist
LINE 1: SELECT COUNT(*) AS "__count" FROM "accounts_goal"
I understand it happened because locally I have 0001 and 0002 migrations, but on the server there are 0012 and etc. migrations. I think I need to delete all old migrations on the server. But I don't know how to do that. Help me please! Thank you)
At first, do not delete a table from the database before the migration. If you change your model, then manage.py migrate will do the thing. Django cannot detect the direct change of database; only knows the change of model script (makemigrations).
Sometimes migration doesn't work for no reasons. In that case, do the following things:
Undo the change of models.py (comment, delete).
manage.py makemigrations app-name.
manage.py migrate
Change the models.py again (as you wish).
Do the migration again.
Also you can try python manage.py migrate --fake.
If there is already a table present, Django will see that the initial migration has already been applied since the table is already present with old schema and therefore not taking the new table with different schema into consideration.
In that case, you need to drop tables in the database you can use python manage.py migrate app-name zero.

Django migrate didn’t launch execute some migration files

I have a Postgres database full of data. And I made several changes to my Django app models.
mange.py makemigrations worked fine and created the migration files. But manage.py migrate execute only one file. And when I launch it again it doesn’t execute the rest as if they are already applied.
I deleted the migration files that were not applied and did another makemigration but it says no changes detected.
Any ideas how to reflect the models changes on the database without losing the data ?
Thanks
Django keeps track of which migrations it has applied already, so when you run the migrate command it will execute only the migrations that Django thinks that are missing.
I deleted the migration files that were not applied and did another makemigration but it says no changes detected.
This was a bad idea, it will make your migrations inconsistent.
If you want to go back in time, instead of deleting migrations, the proper way to do this is by reverting migrations. You can use the same migrate command and specify to which migration point you want your database model to be.
Check this answer for further information about reverting migrations; django revert last migration

How to delete django migrations after squashing them?

Django documentation says we could delete migrations after squashing them:
You should commit this migration but leave the old ones in place; the
new migration will be used for new installs. Once you are sure all
instances of the code base have applied the migrations you squashed,
you can delete them.
Here, does deleting means deleting only the migration files, or the entries in the django_migrations table as well?
Here is some background: I have only the development machine, so just one code base. After squashing some of the migrations that I had already applied, I deleted the files and the database entries. Tested if this is OK by making migrations, it did not find anything. So, everything looked good. Next day, I had to change something, and made migration. When I tried to migrate, it tried to apply the squashed migration too (which was applied part by part before being squashed). So, I had to go back and recreate the entries in the django_migrations table. So, it seems like I had to keep the database entries. I am trying to make sure before I mess up anything again, and understand why it looked fine first, and then tried to apply the squashed migration.
Squashed migrations are never marked as applied, which will be fixed in 1.8.3 (see #24628).
The steps to remove the old migrations are:
Make sure all replaced migrations are applied (or none of them).
Remove the old migration files, remove the replaces attribute from the squashed migrations.
(Workaround) Run ./manage.py migrate <app_label> <squashed_migration> --fake.
The last step won't be necessary when 1.8.3 arrives.
Converting squashed migrations has gotten easier since the question was posted. I posted a small sample project that shows how to squash migrations with circular dependencies, and it also shows how to convert the squashed migration into a regular migration after all the installations have migrated past the squash point.
As the Django documentation says:
You must then transition the squashed migration to a normal migration by:
Deleting all the migration files it replaces.
Updating all migrations that depend on the deleted migrations to depend on the squashed migration instead.
Removing the replaces attribute in the Migration class of the squashed migration (this is how Django tells that it is a squashed migration).
I'm no expert by any means, but I just squashed my migrations, and ended up doing the following:
Ran this query to removed the old migrations (squashed)
DELETE FROM south_migrationhistory;
Run this management command to remove the ghosted migrations
./manage.py migrate --fake --delete-ghost-migrations
Django 1.7 also has squashmigrations

Django-south: "! These migrations are in the database but not on disk:"

I am trying to migrate a database, after modifying the schema in the models.py file of my app in Django. When I try to migrate using ./manage.py migrate <app-name>, it gives the following message:
! These migrations are in the database but not on disk:
As I went through the schemamigration_table and the files, I noticed that for my last schema migration, the file (which added a table and a column in another table successfully) is not present for some reason. Is there any way I could perform my migration without resetting the database?
Yes,
If you are absolutely confident about the migration to have already applied to the database, You can safely use the --fake option.
./manage.py migrate <app-name> --fake
This would forward the migrations to the most recent migration.
--fake: Records the migration sequence as having been applied, but doesn’t actually run it. Useful for Converting An App.

how to change the order of south migrations

I have around fifty migrations in my store app, some of them are schemamigration and some datamigration. Now i want to run 0039_add_column_is_worldwide before 0037_some_values_to_objects. So I changed there name 0037_add_column_is_worldwide and 0039_some_values_to_objects.
It works fine when i did syncdb for new db but while migrating for a new migration in existing db it gives this error.
raise exceptions.InconsistentMigrationHistory(problems)
south.exceptions.InconsistentMigrationHistory: Inconsistent migration history
The following options are available:
--merge: will just attempt the migration ignoring any potential dependency conflicts.
I didn't want to lose my data, so is there anyway to change the order of these migrations?
Migration are stored in DB when ran, so if you already applied these migrations south is going to get lost. Your alternatives:
flush the migration table (will cause all migration to run again if you call migrate)
rollback these migrations (before renaming)
fake these migrations (migrate --fake, but the numbers may conflict with the one in DB anyway)
Rollback seems the safest to me, just be sure everybody in your project do the same.
If you are still in dev and you have no prod database, you can always restart from zero:
flush the south db
migrate --fake
I guess your database has already done "0037_some_values_to_objects".
I would do it like this:
Remove the code inside the forward() and other method in "0037_some_values_to_objects". This migration does nothing. Now add two new migrations.
Rule of thumb: If one system has done a migration, don't delete it. Make it empty.