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
Related
I've got a Django app with a lot of out-of-date migrations. I'd like to remove the old migrations and start fresh.
The app has 14 different "migrations" folders.
Here is what a few of them look like:
Is it safe to remove all the contents from each of these folders? Or, do I have to make sure to only remove some of the files -- and if so which files?
You should never just delete migrations before unapplying them, or it will be a nightmare when you want to apply new migrations.
To unapply migrations you should do the following:
Use the python manage.py migrate your_app_name XXXX in case you want to unapply migrations after the XXXX migration. Otherwise use python manage.py migrate your_app_name zero to completely unapply all migrations.
Remove the .pyc files under /migrations/_pycache_/ that you have unapplied.
Remove the .py files under migrations/ that you have unapplied.
Now you can create new migrations without any headaches.
If what you're looking for is to squash all the migrations into one, do the steps above removing all migrations and then run python manage.py makemigrations your_app_name to create a single migration file. After that just run python manage.py migrate your_app_name and you're done.
That depends. If you have a production database (or any database you cannot simply drop and recreate), then the answer is no, you cannot safely remove migrations.
If you do not have any permanent databases, then yes, you can remove all migrations, run python manage.py makemigrations --initial and it will create fresh migrations based on your current models.
Also, you should check if any of the migrations are custom data migrations written by hand. If there are any, you might want to keep those.
The .pyc files are generally safe to remove, provided the related .py files are still there.
your first screenshot is not Django and looks like a JS project of some sort.
The json and js files are unrelated to the django migrations as well as __pycache__ folder. You can delete all off them.
If you mean "previously applied and no longer needed as the project only needs the latest version of the migrations" you don't want to remove but squash them instead with squashmigrations which reduces the files you have to two, init file and the initial migration file, this way your project still works.
If by remove you mean you no longer need them because you already changed the models so much that the previous migrations aren't even used other than being applied and unapplied without ever being used, doesn't matter, go to step 2 and do that instead of deleting the files manually. When you create migrations on your applications one by one, you also create migration dependency tree, well, django does. And it is really hard to keep track of after some point, if you try to delete everything thinking you can create new migration files with ease, trust me as someone who experienced otherwise, it does not work like that. It is way simpler to let django handle the migration squashing, it optimizes the migration meaning that it also deletes the unused ones in your final state.
More to read at: https://docs.djangoproject.com/en/2.2/topics/migrations/#migration-squashing
Having marked one of the answers provided previously as being accepted, here is a summary of a few things I learned:
Deleting Django migrations is generally a bad idea.
Django keeps track of what's in your db through these migration files, as well as through a table it creates in your db, and if you delete any of this Django will start throwing errors on migrate that can be hard to fix.
I was getting some of those hard-to-fix errors. Here is what I did to fix it:
Ran migrate on the production server.
When I got an error, it would tell me how the db was out of sync with what Django expected. I corrected that manually by directly editing the db with an sql client.
E.g. If it said a key existed that wasn't supposed to exist, I deleted the relevant index from the indicated table.
Or if it said a table existed that wasn't supposed to exist, I backed up the table to a file, and deleted the table. Migrate then created the table, and then I repopulated it with data from the backup.
In the case of many-to-many tables, once Django had re-created them, I deleted all the new Django-created tables, and restored them from a backup created on my local dev system, which had already had all the latest migrations run on it.
Eventually I was able to complete all migrations successfully.
I have a feeling I lucked out and the above won't work in all cases! I've learned a lot about Django and migrations and will be much more careful about this in the future.
when you import from third app:
there are 2 step uninstall it
there are use the 'django_celery_beat' app for example.
step1: clean table
python .\manage.py migrate django_celery_beat zero
step2: remove app from INSTALLED_APPS
there are done!!!
this is django document on this.
How to Reset Migrations
if you are using linux/unix os then you can fire this command. delete all migration directory.
find . -path "/migrations/.py" -not -name "init.py" -delete
find . -path "/migrations/.pyc" -delete
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
I have some questions on Squashing in Django 1.8. I've squashed a few migration files into one but not quite sure how to do the 2 actions as specified in the djangoprojects docs.
After this has been done, you must then transition the squashed migration to a normal initial migration, by:
-Deleting all the migration files it replaces
-Removing the replaces argument in the Migration class of the squashed migration (this is how Django tells that it is a squashed migration)
Do I just delete the migration files in the migration file using normal rm command?
Do I just vim the migration file "0001_squashed_xxx" and remove the part "replaces = []"?
Also, after I run the squashed migration, the migration (original is 0010) became 0001 automatically. Is this the expected behavior?
Any help would be great. Thanks!
Do I just delete the migration files in the migration file using normal rm command?
Do I just vim the migration file "0001_squashed_xxx" and remove the part "replaces = []"?
Yes and yes, but only AFTER you've run the squashed migrations on all your production sites.
Also, you should ensure that none of your other migrations depend on the migrations you're about to delete. If they do, you should change those dependencies to point at the corresponding squashed migrations instead.
Also, after I run the squashed migration, the migration (original is 0010) became 0001 automatically. Is this the expected behavior?
This is because squashed migrations are given the name <start_migration>_squashed_<end_migration>. So if you squashed from 0001_initial to 0010_blah, the squashed migration will have the name 0001_initial_squashed_0010_blah and thus its code will start with 0001. But the numbering doesn't really mean anything, it's just there so that your migrations are nicely ordered when listed in a directory.
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.
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.