djangopostgresqlmigrationwebfaction

Recover deleted Django migrations


On my production server I accidentally deleted my migrations directory in one of my apps. Multiple people work on the app, so at the time of making the app, what we did was push up our model changes without making any migrations locally, and than make the migrations on the production server, and migrate there. We did this because we were having migrations merge issues in the past, and thought this might be a good solution. Since there is no local copy of the migrations folder I fear its gone forever. My question is this. I can access phpPgAdmin in Webfaction, and the database has a django_migrations table. I thought one solution would be to find the latest migrations, lets say for example 0009_migration.py, and than simply rename a new migration file, 0010_migration.py for my next migration if I ever make any model changes in the future in that app. That way I can simple run migrate, and it will only be considered with the migration that it has yet to run, 0010_migration.py. But just out of curiosity, is there some command that will look at your PostgreSQL database, and create the migration files in your app migrations directory from the migration records it has on file in the django_migrations table ?

I guess a simpler way to ask this is "Is there a way to reverse engineer django_migrations table rows into migrations.py files ?" Here is an image of a django_migration table row I have in PostgreSQL, and what I would want the file to look like, just with different commands.

Django Migration

class Migration(migrations.Migration):

    dependencies = [
        ('portfolio', '0001_initial'),
    ]

    operations = [
        migrations.AddField(
            model_name='project',
            name='contact_form',
            field=models.BooleanField(default=False),
        ),
    ]

PostgreSQL django_migrations table row enter image description here


Solution

    1. Delete from the migration table of your database all entires for that one app whose migration files were deleted.

    2. $ python manage.py makemigrations <app>

    This creates 1 new migration file (an inital migration).

    1. $ python manage.py migrate <app> --fake

    Writes the initial migration into migration table but does not touch any other table (does not actually migrate).

    That should work as long as there were no changes to the app whose migration files were deleted.

    This might solve the problem of accidently deleting migrations files (assuming they were auto-created by manage.py and not manipulated). But I don't know whether it is able or if it is recommendable to refactor the migrations table - it also might cause to adapt either the auto-creation of migration files, requires the manual manipulation of any migration file after it was auto-created or even requires to override the django backend.

    #Edit Answer to the additional question in the comment:

    So if you delete the migrations files of an app you just delete the description and history of the models's schemas of that app. Same goes for the entries in your migration table: You just delete information about which migration files where applied to your database.

    So what the actual solution I suggested does is the following:

    1. Delete information about which migration files were applied to your database for one specific app
    2. Create one new migration files of that one app
    3. Write the migration file to the migration table but do not apply it. << This is why there must not be any changes in your app's models since the migration files where deleted.

    Why is it necessary to delete existing entries in the migration table?

    As you can see in the image you provided in your question, entries in the migration store the name of any applied migration files. Not deleting those entries would cause manage.py migrate assuming migration files with the same name (or number - I'm not 100% aware of this) has already been applied. So those would be skipped on migrations.