11

I personally like django for its MVC ideals. But while i am running Django migrations in version 1.7 each and every migrations i do in it is stored inside the migrations directory. If i delete those file it is throwing an error while migration.

I Tested like this. I created a new Django project and initiated a git repo . I ran some 3-4 migrations in Django which resulted in 3-4 migration files under the migrations directory. I tried deleting the very older migration files i.e (1st and 2nd migration files) and tried to run

python manage.py makemigrations

which does cause some error like "migration files not found". Later i did a git stash which restored the deleted files. Now i tried to run the same command again and it was working fine.

What my question is if a person runs some 50 changes in db during development all the migration files are stored in migrations directory. Is it possible to delete those files and do changes to db again without any interruption?

sathya Narrayanan
  • 499
  • 1
  • 5
  • 16
  • Are you developing against an existing DB that has the migrations your wondering about applied? If so, you don't want to delete those mogrations. If you are starting a new db from scratch with syncdb then you don't need any of your old migrations. So I think the answer is "depends on your DB setup" – Sean Azlin Feb 09 '15 at 07:20
  • Putting my previous comment another way, the easiest way to discard your 50 migrations would be to just blow away the db (and it's 50 migrations) and start from scratch given your current models. Is that an option for you? – Sean Azlin Feb 09 '15 at 07:25
  • 1
    i am using existing db. so if i delete my db then i can delete the migration files is it right? – sathya Narrayanan Feb 09 '15 at 07:39
  • 1
    Right, because sync db will build a blank db using your current models. It'll then optionally populate the db using any initial fixtures. Conceptually, there is no longer anything that you've migrated from at such a point, so you don't need to keep around your old migrations for your old db. They are no longer relevant. You might also appreciate knowing that when you apply migrations to a db it's also recording those migrations in a special table in the db itself. That's why things go haywire when you just delete the migration files. They have to stay in sync with the migration table. – Sean Azlin Feb 09 '15 at 07:54
  • That explains it thank you. – sathya Narrayanan Feb 09 '15 at 08:26

6 Answers6

14

The answer is "it depends".

If you are working against a production DB, or some DB that can't periodically blow away for whatever reason, then you absolutely want to keep around the migration files that you've applied to your DB. They should be checked into source control with the rest of your code.

Now, for a situation like yours, the easiest way to discard your 50 migrations would be to just blow away the db (and it's 50 migrations) and start from scratch given your current models. It's oftentimes a good idea to do this periodically as you evolve your models during development.

Its ok to blow away your models when you blow away your DB because syncdb will build a blank db using your current models. It'll then optionally populate the db using any initial fixtures. Conceptually, there is no longer anything that you've migrated from at such a point, so you don't need to keep around your old migrations for your old db. They are no longer relevant.

It's not usually good to delete migration files that have been applied to your DB unless you are either 1) blowing away the DB altogether, or 2) reverting the migrations first.

You might also appreciate knowing that when you apply migrations to a db it's also recording those migrations in a special table in the db itself. That's why things go haywire when you just delete the migration files. They have to stay in sync with the migration table

Sean Azlin
  • 886
  • 7
  • 21
  • I have a situation where I've changed my models.py file and for some reason the resultant migration script generated by `python manage.py makemigrations` is incorrect (deleting a field I did not intend to delete). Is it safe to delete this migration script before I have actually run the migration? Thanks – deusofnull Sep 10 '18 at 14:39
  • @deusofnull We run into this often. It's a good reminder to always inspect your auto-generated migration files before running them. The typical approach I take is to generate a migration file, inspect it manually, and remove any statements in the file I don't actually want. Then migrate. Note that subsequent makemigration commands will usually regenerate the same statements that you previously deleted, which may or may not be what you want. If you know you'll never want to run a migration that keeps getting auto-generated, you can create a dedicated migration for just that and fake it. – Sean Azlin Oct 26 '18 at 17:29
2

The answer is "Do not delete migration files". To understand why we shouldn't delete migration files, you need to understand how migration works in frameworks. Migration files are the history of your database. One migration file is created based on the migration files created in the past. Deleting migration files means losing your history. This historical info is recorded in the django_migrations table in your database. if you delete migration files, you will get dependency errors. So Don't try to lose your history by deleting your migration files.

code.dev.world
  • 221
  • 2
  • 12
1

If you want to keep your DB, but decrease the number of migration files, one option is squashing the migrations into one (or few, if complex dependencies) migration.

From the official documentation:

You are encouraged to make migrations freely and not worry about how many you have; the migration code is optimized to deal with hundreds at a time without much slowdown. However, eventually you will want to move back from having several hundred migrations to just a few, and that’s where squashing comes in.

Before squashing, you should be aware that "model interdependencies in Django can get very complex, and squashing may result in migrations that do not run", and therefore manual work may be needed.

For detailed information about how to make the squashing, refer to the docs: https://docs.djangoproject.com/en/dev/topics/migrations/#squashing-migrations

Niko Föhr
  • 28,336
  • 10
  • 93
  • 96
1

If models match database it is safe to delete migration files.

Currently, with Django 3 I can safely remove the migrations directory, then run python manage.py makemigrations myapp and python manage.py migrate. After that I have 0001_initial.py migration file and my production database is intact. This works when models already match database.

MartinsM
  • 110
  • 7
0

It probably isn't a good idea (apparently), but if you are going to do it... do not remove the __init__.py files.

In *nix:

cd [your project directory]
find . -path "*/migrations/[0-9][0-9][0-9][0-9]_*.py" -delete
find . -path "*/migrations/*.pyc"  -delete
ErichBSchulz
  • 15,047
  • 5
  • 57
  • 61
0

In my opinion, it would be a bad idea. You can always roll back migrations if you make a mistake. Also, as migrations grow too large, you can also "squash" them. I learned about this from an article written by DoorDash.

You are encouraged to make migrations freely and not worry about how many you have; the migration code is optimized to deal with hundreds at a time without much slowdown. However, eventually you will want to move back from having several hundred migrations to just a few, and that’s where squashing comes in.

Squashing migrations: https://docs.djangoproject.com/en/3.2/topics/migrations/#squashing-migrations DoorDash article: https://doordash.engineering/2017/05/15/tips-for-building-high-quality-django-apps-at-scale/

joshlsullivan
  • 1,375
  • 2
  • 14
  • 21