45

So I'm rapidly iterating on a django app at the moment and I'm constantly adjusting models.py. Over the course of a day or two of programming and testing I generate a couple dozen migration files. Sometimes I really tear the schema apart and completely re-do it. This causes the migration process to complain a great deal about defaults and null values and so on. If possible, I would just like to scratch all the migration stuff and re-start the migrations now that I finally know what I'm doing. My approach thus far has been the following:

  1. delete everything in the migrations folder except for __init__.py.
  2. drop into my PostgreSQL console and do: DELETE FROM south_migrationhistory WHERE app_name='my_app';
  3. while at the PostgreSQL console, drop all of the tables associated with my_app.
  4. re-run ./manage.py makemigrations my_app - this generates a 0001_initial.py file in my migrations folder.
  5. run ./manage migrate my_app - I expect this command to re-build all my tables, but instead it says: "No migrations to apply."

What gives?

Also, is the south_migrationhistory database table still in play now that I've dumped South and have switched to Django 1.7?

Thanks.

tadasajon
  • 14,276
  • 29
  • 92
  • 144
  • 5
    Note that you can also delete the migration history from within Django (e.g. the shell): `from django.db.migrations.recorder import MigrationRecorder; MigrationRecorder.Migration.objects.filter(app=my_app).delete()` – Kevin Christopher Henry Oct 09 '14 at 17:03
  • 2
    duplicate/related: [How to reset migrations in Django 1.7?](http://stackoverflow.com/questions/23755523/) – Afriza N. Arief Apr 16 '15 at 06:31

2 Answers2

36

So the step-by-step plan I outlined in my question does work, but instead of deleting rows from the south_migrationhistory database table, I had to delete rows from the django_migrations database table.

The command is: DELETE FROM django_migrations WHERE app='my_app'

Once this is done, you will be able to re-run your migrations from scratch.

Afriza N. Arief
  • 7,696
  • 5
  • 47
  • 74
tadasajon
  • 14,276
  • 29
  • 92
  • 144
  • 1
    For future reference, I also had to delete everything inside the app's `migrations` folder. – JakeCowton Feb 01 '15 at 20:42
  • 2
    @jon Doesn't it say the something like the relations already exist/ table already exists. because the tables are already there and migrate command tries to create them again – Mukund Gandlur May 03 '16 at 05:49
24

I just wanted to put all the steps into a command format:

NOTE: The commands below are pretty destructive, it is a means to start from scratch as the OP asked.

After a comment from mikeb I thought to add this line:

PRE - CHECK WHAT FILES YOU WOULD DELETE

find . -path "*migrations*" -name "*.py" -not -path "*__init__*"

Then, adjust the command in step 1 to one that works for your dev environment.

  1. remove all the migrations from all the apps:
find . -path "*migrations*" -name "*.py" -not -path "*__init__*" -exec rm {} \; # make sure to be in your projects path
  1. recreate the whole database:
sudo -u postgres bash -c "psql -c \"DROP DATABASE rootedin;\""
sudo -u postgres bash -c "psql -c \"CREATE DATABASE rootedin;\""
sudo -u postgres bash -c "psql -c \"GRANT ALL PRIVILEGES ON DATABASE rootedin to vagrant;\"" # vagrant is my current user
  1. get your db up to date:
python3 manage.py makemigrations
python3 manage.py migrate
Pedram Parsian
  • 3,750
  • 3
  • 19
  • 34
mimoralea
  • 9,590
  • 7
  • 58
  • 59
  • 4
    CAUTION: Your find and delete statement will delete way more than you want to, potentially. I ran just the find and discovered that it would have deleted a *bunch* of stuff in my virtualenv install, so I'd advise anyone reading this to beware of doing that. – mikeb May 22 '15 at 11:06
  • That's a good note Mike, any suggestions on how to make it better? I don't use virtualenv so I can see why `*migrations*` can pick up a lot more. – mimoralea May 22 '15 at 14:08
  • Well, with virtualenv you can call your directory anything, so if your virtualenv install was in the `venv` directory you could add another `-not -path "venv/"` or something. Perhaps easier and without having to know your virtualenv directory (or even if you're using it or not) you could use `-maxdepth 2` – mikeb May 22 '15 at 17:53
  • 3
    If you don't want to be quite so destructive, say for example you want to reduce your migrations but not remove data from your models, you can skip #2 and then run `python3 manage.py migrate --fake` to apply the migrations without executing the SQL commands. – shapiromatron Jun 23 '15 at 14:36