Django Migrations

Django Migrations

         Migrations are Django’s way of propagating changes you make to your models (adding a field, deleting a model, etc.) into your database schema. They’re designed to be mostly automatic.

         Prior to Django version 1.7, Django only supported adding new models to the database; it was not possible to alter or remove existing models via the syncdb command.

Benifits With Migrations:

  • Speed up the notoriously slow process of changing a database schema.
  • Make it easy to use git to track your database schema and its associated changes. Databases simply aren’t aware of git or other version control systems. Git is awesome for code, but not so much for database schemas.
  • Provide an easy way to maintain fixture data linked to the appropriate schema.
  • Keep the code and schema in sync.


Commands:

      makemigrations :
            Which is responsible for creating new migrations based on the changes you have made                to your models.
      sqlmigrate :
             Which displays the SQL statements for a migration.
      migrate :
             Which is responsible for applying migrations, as well as unapplying and listing their status.

MIGRATION_MODULES:

      Default:

     MIGRATION_MODULES = {}   //    in settings.py file

            A dictionary specifying the package where migration modules can be found on a per-app             basis. The default value of this setting is an empty dictionary, but the default package name             for migration modules is migrations.
      Example:

     MIGRATION_MODULES = {'aptuz': 'aptuz.db_migrations'}

            Migrations pertaining to the aptuz app will be contained in aptuz.db_migrations package.

            If you provide the app_label argument, makemigrations will automatically create the package if it doesn’t already exist.

Makemigrations:

       $ python manage.py makemigrations

             Creates migrations files for all apps

      $ python manage.py makemigrations your_app_label

          Creates migrations files for specified app

      $ python manage.py makemigrations --empty your_app_label

             Creates empty migration file for specified app

      Example:


            from django.db import models, migrations
            class Migration(migrations.Migration):
                  dependencies = [
                        ('aptuz', '0001_initial'),
                  ]
                  operations = [
                  ]

  New in Django 1.8

       $ python manage.py makemigrations --name changed_my_model your_app_label

       Creates migartions file with given name

Sqlmigrate:

       $ python manage.py sqlmigrate your_app_label migrations_file_name

            This returns sql command those migrations


How Migrations Know What to Migrate?:

      By default Django will never run a migration more than once on the same database. This is managed by a table called django_migrations that is created in your database the first time migrations are ran. For each migration that is ran or faked, a new row is inserted into the table

Migrate :


      $ python manage.py migrate


            Database schema changes for all migrations

      $ python manage.py migrate your_app_label


            Database schema changes specified app

      $ python manage.py migrate --fake your_app_label


            No changes in database schema for that app migrations and a new row is inserted into the      table

   New in Django 1.8

       $ python manage.py migrate --fake-initial

      The --fake-initial flag was added to migrate; previously, initial migrations were always automatically fake-applied if existing tables were detected.

      Django will detect that you have an initial migration and that the tables it wants to create already exist, and will mark the migration as already applied

      Without the --fake-initial flag, the migrate command would error out because the tables it wants to create already exist.


Undo all Migrations:

      If you want to undo all the migrations for a particular app, you can migrate to a special migration called zero.

      Example:

            $ python manage.py migrate your_app_label zero

      It will undo/reverse all the migrations for your app. In addition to using zero; you can also use any arbitrary migration, and if that migration is in the past then the database will be rolled back to the state of that migration, or rolled forward if the migration hasn’t yet ran


Migration Files:

      dependencies : a list of migrations this one depends on.
      operations : a list of Operation classes that define what this migration does

      Example:

             from __future__ import unicode_literals
             from django.db import models, migrations
             class Migration(migrations.Migration):
                  dependencies = [
                  ]
                  operations = [
                        migrations.CreateModel(
                        name='Aptuz',
                        fields=[
                        ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                        ('name', models.CharField(max_length=40)),
                        ('join_date', models.DateTimeField(verbose_name=b'date published')),
                        ('salary', models.IntegerField(default=0)),
                        ('cell', models.CharField(max_length=15)),
                        ('address', models.CharField(max_length=200)),
                        ],
                        options={
                        },
                        bases=(models.Model,),
                        ),
                  ]


Migration Operations:

      CreateModel:
            You guessed it: this creates a new model. See the migration above for an example.
      DeleteModel:
             Removes a table from the database; just pass in the name of the model.
      RenameModel:
            Given the old_name and new_name, this renames the model.
      AlterModelTable:
             Changes the name of the table associated with a model. Same as the db_table option.
      AlterUniqueTogether:
             Changes unique constraints.
      AlteIndexTogether:
            Changes the set of custom indexes for the model.
      AddField:
            Just like it sounds.
      RemoveField:
            We don’t want that field anymore… just drop it.
      RenameField:
            Given model_name, old_name and new_name, this changes the field with old_name to new_name.


Sources:
       1. https://realpython.com/blog/python/django-migrations-a-primer/