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/