|
@@ -57,6 +57,7 @@ Then, to leverage this in your migrations, do the following::
|
|
|
|
|
|
def forwards(apps, schema_editor):
|
|
|
# Your migration code goes here
|
|
|
+ ...
|
|
|
|
|
|
class Migration(migrations.Migration):
|
|
|
|
|
@@ -83,44 +84,76 @@ Therefore, the following steps should be taken. In this example, we'll add a
|
|
|
non-nullable :class:`~django.db.models.UUIDField` with a default value. Modify
|
|
|
the respective field according to your needs.
|
|
|
|
|
|
-* Add the field on your model with ``default=...`` and ``unique=True``
|
|
|
- arguments. In the example, we use ``uuid.uuid4`` for the default.
|
|
|
+* Add the field on your model with ``default=uuid.uuid4`` and ``unique=True``
|
|
|
+ arguments (choose an appropriate default for the type of the field you're
|
|
|
+ adding).
|
|
|
|
|
|
-* Run the :djadmin:`makemigrations` command.
|
|
|
+* Run the :djadmin:`makemigrations` command. This should generate a migration
|
|
|
+ with an ``AddField`` operation.
|
|
|
|
|
|
-* Edit the created migration file.
|
|
|
+* Generate two empty migration files for the same app by running
|
|
|
+ ``makemigrations myapp --empty`` twice. We've renamed the migration files to
|
|
|
+ give them meaningful names in the examples below.
|
|
|
+
|
|
|
+* Copy the ``AddField`` operation from the auto-generated migration (the first
|
|
|
+ of the three new files) to the last migration and change ``AddField`` to
|
|
|
+ ``AlterField``. For example:
|
|
|
+
|
|
|
+ .. snippet::
|
|
|
+ :filename: 0006_remove_uuid_null.py
|
|
|
+
|
|
|
+ # -*- coding: utf-8 -*-
|
|
|
+ from __future__ import unicode_literals
|
|
|
+
|
|
|
+ from django.db import migrations, models
|
|
|
+ import uuid
|
|
|
|
|
|
- The generated migration class should look similar to this::
|
|
|
|
|
|
class Migration(migrations.Migration):
|
|
|
|
|
|
dependencies = [
|
|
|
- ('myapp', '0003_auto_20150129_1705'),
|
|
|
+ ('myapp', '0005_populate_uuid_values'),
|
|
|
]
|
|
|
|
|
|
operations = [
|
|
|
- migrations.AddField(
|
|
|
+ migrations.AlterField(
|
|
|
model_name='mymodel',
|
|
|
name='uuid',
|
|
|
- field=models.UUIDField(max_length=32, unique=True, default=uuid.uuid4),
|
|
|
+ field=models.UUIDField(default=uuid.uuid4, unique=True),
|
|
|
),
|
|
|
]
|
|
|
|
|
|
- You will need to make three changes:
|
|
|
+* Edit the first migration file. The generated migration class should look
|
|
|
+ similar to this:
|
|
|
+
|
|
|
+ .. snippet::
|
|
|
+ :filename: 0004_add_uuid_field.py
|
|
|
+
|
|
|
+ class Migration(migrations.Migration):
|
|
|
+
|
|
|
+ dependencies = [
|
|
|
+ ('myapp', '0003_auto_20150129_1705'),
|
|
|
+ ]
|
|
|
|
|
|
- * Add a second :class:`~django.db.migrations.operations.AddField` operation
|
|
|
- copied from the generated one and change it to
|
|
|
- :class:`~django.db.migrations.operations.AlterField`.
|
|
|
+ operations = [
|
|
|
+ migrations.AddField(
|
|
|
+ model_name='mymodel',
|
|
|
+ name='uuid',
|
|
|
+ field=models.UUIDField(default=uuid.uuid4, unique=True),
|
|
|
+ ),
|
|
|
+ ]
|
|
|
|
|
|
- * On the first operation (``AddField``), change ``unique=True`` to
|
|
|
- ``null=True`` -- this will create the intermediary null field.
|
|
|
+ Change ``unique=True`` to ``null=True`` -- this will create the intermediary
|
|
|
+ null field and defer creating the unique constraint until we've populated
|
|
|
+ unique values on all the rows.
|
|
|
|
|
|
- * Between the two operations, add a
|
|
|
- :class:`~django.db.migrations.operations.RunPython` or
|
|
|
- :class:`~django.db.migrations.operations.RunSQL` operation to generate a
|
|
|
- unique value (UUID in the example) for each existing row.
|
|
|
+* In the first empty migration file, add a
|
|
|
+ :class:`~django.db.migrations.operations.RunPython` or
|
|
|
+ :class:`~django.db.migrations.operations.RunSQL` operation to generate a
|
|
|
+ unique value (UUID in the example) for each existing row. For example:
|
|
|
|
|
|
- The resulting migration should look similar to this::
|
|
|
+ .. snippet::
|
|
|
+ :filename: 0005_populate_uuid_values.py
|
|
|
|
|
|
# -*- coding: utf-8 -*-
|
|
|
from __future__ import unicode_literals
|
|
@@ -137,25 +170,15 @@ the respective field according to your needs.
|
|
|
class Migration(migrations.Migration):
|
|
|
|
|
|
dependencies = [
|
|
|
- ('myapp', '0003_auto_20150129_1705'),
|
|
|
+ ('myapp', '0004_add_uuid_field'),
|
|
|
]
|
|
|
|
|
|
operations = [
|
|
|
- migrations.AddField(
|
|
|
- model_name='mymodel',
|
|
|
- name='uuid',
|
|
|
- field=models.UUIDField(default=uuid.uuid4, null=True),
|
|
|
- ),
|
|
|
# omit reverse_code=... if you don't want the migration to be reversible.
|
|
|
migrations.RunPython(gen_uuid, reverse_code=migrations.RunPython.noop),
|
|
|
- migrations.AlterField(
|
|
|
- model_name='mymodel',
|
|
|
- name='uuid',
|
|
|
- field=models.UUIDField(default=uuid.uuid4, unique=True),
|
|
|
- ),
|
|
|
]
|
|
|
|
|
|
-* Now you can apply the migration as usual with the :djadmin:`migrate` command.
|
|
|
+* Now you can apply the migrations as usual with the :djadmin:`migrate` command.
|
|
|
|
|
|
Note there is a race condition if you allow objects to be created while this
|
|
|
migration is running. Objects created after the ``AddField`` and before
|