123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851 |
- ==========
- Migrations
- ==========
- .. module:: django.db.migrations
- :synopsis: Schema migration support for Django models
- .. versionadded:: 1.7
- 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, but you'll need to know when to make
- migrations, when to run them, and the common problems you might run into.
- A Brief History
- ---------------
- Prior to 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 (the predecessor to :djadmin:`migrate`).
- Third-party tools, most notably `South <http://south.aeracode.org>`_,
- provided support for these additional types of change, but it was considered
- important enough that support was brought into core Django.
- The Commands
- ------------
- There are several commands which you will use to interact with migrations
- and Django's handling of database schema:
- * :djadmin:`migrate`, which is responsible for applying migrations, as well as
- unapplying and listing their status.
- * :djadmin:`makemigrations`, which is responsible for creating new migrations
- based on the changes you have made to your models.
- * :djadmin:`sqlmigrate`, which displays the SQL statements for a migration.
- It's worth noting that migrations are created and run on a per-app basis.
- In particular, it's possible to have apps that *do not use migrations* (these
- are referred to as "unmigrated" apps) - these apps will instead mimic the
- legacy behavior of just adding new models.
- You should think of migrations as a version control system for your database
- schema. ``makemigrations`` is responsible for packaging up your model changes
- into individual migration files - analogous to commits - and ``migrate`` is
- responsible for applying those to your database.
- The migration files for each app live in a "migrations" directory inside
- of that app, and are designed to be committed to, and distributed as part
- of, its codebase. You should be making them once on your development machine
- and then running the same migrations on your colleagues' machines, your
- staging machines, and eventually your production machines.
- .. note::
- It is possible to override the name of the package which contains the
- migrations on a per-app basis by modifying the :setting:`MIGRATION_MODULES`
- setting.
- Migrations will run the same way on the same dataset and produce consistent
- results, meaning that what you see in development and staging is, under the
- same circumstances, exactly what will happen in production.
- Django will make migrations for any change to your models or fields - even
- options that don't affect the database - as the only way it can reconstruct
- a field correctly is to have all the changes in the history, and you might
- need those options in some data migrations later on (for example, if you've
- set custom validators).
- Backend Support
- ---------------
- Migrations are supported on all backends that Django ships with, as well
- as any third-party backends if they have programmed in support for schema
- alteration (done via the :doc:`SchemaEditor </ref/schema-editor>` class).
- However, some databases are more capable than others when it comes to
- schema migrations; some of the caveats are covered below.
- PostgreSQL
- ~~~~~~~~~~
- PostgreSQL is the most capable of all the databases here in terms of schema
- support; the only caveat is that adding columns with default values will
- cause a full rewrite of the table, for a time proportional to its size.
- For this reason, it's recommended you always create new columns with
- ``null=True``, as this way they will be added immediately.
- MySQL
- ~~~~~
- MySQL lacks support for transactions around schema alteration operations,
- meaning that if a migration fails to apply you will have to manually unpick
- the changes in order to try again (it's impossible to roll back to an
- earlier point).
- In addition, MySQL will fully rewrite tables for almost every schema operation
- and generally takes a time proportional to the number of rows in the table to
- add or remove columns. On slower hardware this can be worse than a minute per
- million rows - adding a few columns to a table with just a few million rows
- could lock your site up for over ten minutes.
- Finally, MySQL has reasonably small limits on name lengths for columns, tables
- and indexes, as well as a limit on the combined size of all columns an index
- covers. This means that indexes that are possible on other backends will
- fail to be created under MySQL.
- SQLite
- ~~~~~~
- SQLite has very little built-in schema alteration support, and so Django
- attempts to emulate it by:
- * Creating a new table with the new schema
- * Copying the data across
- * Dropping the old table
- * Renaming the new table to match the original name
- This process generally works well, but it can be slow and occasionally
- buggy. It is not recommended that you run and migrate SQLite in a
- production environment unless you are very aware of the risks and
- its limitations; the support Django ships with is designed to allow
- developers to use SQLite on their local machines to develop less complex
- Django projects without the need for a full database.
- Workflow
- --------
- Working with migrations is simple. Make changes to your models - say, add
- a field and remove a model - and then run :djadmin:`makemigrations`::
- $ python manage.py makemigrations
- Migrations for 'books':
- 0003_auto.py:
- - Alter field author on book
- Your models will be scanned and compared to the versions currently
- contained in your migration files, and then a new set of migrations
- will be written out. Make sure to read the output to see what
- ``makemigrations`` thinks you have changed - it's not perfect, and for
- complex changes it might not be detecting what you expect.
- Once you have your new migration files, you should apply them to your
- database to make sure they work as expected::
- $ python manage.py migrate
- Operations to perform:
- Synchronize unmigrated apps: sessions, admin, messages, auth, staticfiles, contenttypes
- Apply all migrations: books
- Synchronizing apps without migrations:
- Creating tables...
- Installing custom SQL...
- Installing indexes...
- Installed 0 object(s) from 0 fixture(s)
- Running migrations:
- Applying books.0003_auto... OK
- The command runs in two stages; first, it synchronizes unmigrated apps
- (performing the same functionality that ``syncdb`` used to provide), and
- then it runs any migrations that have not yet been applied.
- Once the migration is applied, commit the migration and the models change
- to your version control system as a single commit - that way, when other
- developers (or your production servers) check out the code, they'll
- get both the changes to your models and the accompanying migration at the
- same time.
- Version control
- ~~~~~~~~~~~~~~~
- Because migrations are stored in version control, you'll occasionally
- come across situations where you and another developer have both committed
- a migration to the same app at the same time, resulting in two migrations
- with the same number.
- Don't worry - the numbers are just there for developers' reference, Django
- just cares that each migration has a different name. Migrations specify which
- other migrations they depend on - including earlier migrations in the same
- app - in the file, so it's possible to detect when there's two new migrations
- for the same app that aren't ordered.
- When this happens, Django will prompt you and give you some options. If it
- thinks it's safe enough, it will offer to automatically linearize the two
- migrations for you. If not, you'll have to go in and modify the migrations
- yourself - don't worry, this isn't difficult, and is explained more in
- :ref:`migration-files` below.
- Dependencies
- ------------
- While migrations are per-app, the tables and relationships implied by
- your models are too complex to be created for just one app at a time. When
- you make a migration that requires something else to run - for example,
- you add a ``ForeignKey`` in your ``books`` app to your ``authors`` app - the
- resulting migration will contain a dependency on a migration in ``authors``.
- This means that when you run the migrations, the ``authors`` migration runs
- first and creates the table the ``ForeignKey`` references, and then the migration
- that makes the ``ForeignKey`` column runs afterwards and creates the constraint.
- If this didn't happen, the migration would try to create the ``ForeignKey``
- column without the table it's referencing existing and your database would
- throw an error.
- This dependency behavior affects most migration operations where you
- restrict to a single app. Restricting to a single app (either in
- ``makemigrations`` or ``migrate``) is a best-efforts promise, and not
- a guarantee; any other apps that need to be used to get dependencies correct
- will be.
- .. _unmigrated-dependencies:
- Be aware, however, that unmigrated apps cannot depend on migrated apps, by the
- very nature of not having migrations. This means that it is not generally
- possible to have an unmigrated app have a ``ForeignKey`` or ``ManyToManyField``
- to a migrated app; some cases may work, but it will eventually fail.
- .. warning::
- Even if things appear to work with unmigrated apps depending on migrated
- apps, Django may not generate all the necessary foreign key constraints!
- This is particularly apparent if you use swappable models (e.g.
- ``AUTH_USER_MODEL``), as every app that uses swappable models will need
- to have migrations if you're unlucky. As time goes on, more and more
- third-party apps will get migrations, but in the meantime you can either
- give them migrations yourself (using :setting:`MIGRATION_MODULES` to
- store those modules outside of the app's own module if you wish), or
- keep the app with your user model unmigrated.
- .. _migration-files:
- Migration files
- ---------------
- Migrations are stored as an on-disk format, referred to here as
- "migration files". These files are actually just normal Python files with
- an agreed-upon object layout, written in a declarative style.
- A basic migration file looks like this::
- from django.db import migrations, models
- class Migration(migrations.Migration):
- dependencies = [("migrations", "0001_initial")]
- operations = [
- migrations.DeleteModel("Tribble"),
- migrations.AddField("Author", "rating", models.IntegerField(default=0)),
- ]
- What Django looks for when it loads a migration file (as a Python module) is
- a subclass of ``django.db.migrations.Migration`` called ``Migration``. It then
- inspects this object for four attributes, only two of which are used
- most of the time:
- * ``dependencies``, a list of migrations this one depends on.
- * ``operations``, a list of ``Operation`` classes that define what this
- migration does.
- The operations are the key; they are a set of declarative instructions which
- tell Django what schema changes need to be made. Django scans them and
- builds an in-memory representation of all of the schema changes to all apps,
- and uses this to generate the SQL which makes the schema changes.
- That in-memory structure is also used to work out what the differences are
- between your models and the current state of your migrations; Django runs
- through all the changes, in order, on an in-memory set of models to come
- up with the state of your models last time you ran ``makemigrations``. It
- then uses these models to compare against the ones in your ``models.py`` files
- to work out what you have changed.
- You should rarely, if ever, need to edit migration files by hand, but
- it's entirely possible to write them manually if you need to. Some of the
- more complex operations are not autodetectable and are only available via
- a hand-written migration, so don't be scared about editing them if you have to.
- Custom fields
- ~~~~~~~~~~~~~
- You can't modify the number of positional arguments in an already migrated
- custom field without raising a ``TypeError``. The old migration will call the
- modified ``__init__`` method with the old signature. So if you need a new
- argument, please create a keyword argument and add something like
- ``assert kwargs.get('argument_name') is not None`` in the constructor.
- .. _using-managers-in-migrations:
- Model managers
- ~~~~~~~~~~~~~~
- .. versionadded:: 1.8
- You can optionally serialize managers into migrations and have them available
- in :class:`~django.db.migrations.operations.RunPython` operations. This is done
- by defining a ``use_in_migrations`` attribute on the manager class::
- class MyManager(models.Manager):
- use_in_migrations = True
- class MyModel(models.Model):
- objects = MyManager()
- If you are using the :meth:`~django.db.models.from_queryset` function to
- dynamically generate a manager class, you need to inherit from the generated
- class to make it importable::
- class MyManager(MyBaseManager.from_queryset(CustomQuerySet)):
- use_in_migrations = True
- class MyModel(models.Model):
- objects = MyManager()
- Please refer to the notes about :ref:`historical-models` in migrations to see
- the implications that come along.
- Adding migrations to apps
- -------------------------
- Adding migrations to new apps is straightforward - they come preconfigured to
- accept migrations, and so just run :djadmin:`makemigrations` once you've made
- some changes.
- If your app already has models and database tables, and doesn't have migrations
- yet (for example, you created it against a previous Django version), you'll
- need to convert it to use migrations; this is a simple process::
- $ python manage.py makemigrations your_app_label
- This will make a new initial migration for your app. Now, when you run
- :djadmin:`migrate`, 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.
- Note that this only works given two things:
- * You have not changed your models since you made their tables. For migrations
- to work, you must make the initial migration *first* and then make changes,
- as Django compares changes against migration files, not the database.
- * You have not manually edited your database - Django won't be able to detect
- that your database doesn't match your models, you'll just get errors when
- migrations try to modify those tables.
- .. versionadded:: 1.8
- If you want to give the migration(s) a meaningful name instead of a generated one,
- you can use the :djadminopt:`--name` option::
- $ python manage.py makemigrations --name changed_my_model your_app_label
- .. _historical-models:
- Historical models
- -----------------
- When you run migrations, Django is working from historical versions of your
- models stored in the migration files. If you write Python code using the
- :class:`~django.db.migrations.operations.RunPython` operation, or if you have
- ``allow_migrate`` methods on your database routers, you will be exposed to
- these versions of your models.
- Because it's impossible to serialize arbitrary Python code, these historical
- models will not have any custom methods that you have defined. They will,
- however, have the same fields, relationships, managers (limited to those with
- ``use_in_migrations = True``) and ``Meta`` options (also versioned, so they may
- be different from your current ones).
- .. warning::
- This means that you will NOT have custom ``save()`` methods called on objects
- when you access them in migrations, and you will NOT have any custom
- constructors or instance methods. Plan appropriately!
- References to functions in field options such as ``upload_to`` and
- ``limit_choices_to`` and model manager declarations with managers having
- ``use_in_migrations = True`` are serialized in migrations, so the functions and
- classes will need to be kept around for as long as there is a migration
- referencing them. Any :doc:`custom model fields </howto/custom-model-fields>`
- will also need to be kept, since these are imported directly by migrations.
- In addition, the base classes of the model are just stored as pointers, so you
- must always keep base classes around for as long as there is a migration that
- contains a reference to them. On the plus side, methods and managers from these
- base classes inherit normally, so if you absolutely need access to these you
- can opt to move them into a superclass.
- .. _migrations-removing-model-fields:
- Considerations when removing model fields
- -----------------------------------------
- .. versionadded:: 1.8
- Similar to the "references to historical functions" considerations described in
- the previous section, removing custom model fields from your project or
- third-party app will cause a problem if they are referenced in old migrations.
- To help with this situation, Django provides some model field attributes to
- assist with model field deprecation using the :doc:`system checks framework
- </topics/checks>`.
- Add the ``system_check_deprecated_details`` attribute to your model field
- similar to the following::
- class IPAddressField(Field):
- system_check_deprecated_details = {
- 'msg': (
- 'IPAddressField has been deprecated. Support for it (except '
- 'in historical migrations) will be removed in Django 1.9.'
- ),
- 'hint': 'Use GenericIPAddressField instead.', # optional
- 'id': 'fields.W900', # pick a unique ID for your field.
- }
- After a deprecation period of your choosing (two major releases for fields in
- Django itself), change the ``system_check_deprecated_details`` attribute to
- ``system_check_removed_details`` and update the dictionary similar to::
- class IPAddressField(Field):
- system_check_removed_details = {
- 'msg': (
- 'IPAddressField has been removed except for support in '
- 'historical migrations.'
- ),
- 'hint': 'Use GenericIPAddressField instead.',
- 'id': 'fields.E900', # pick a unique ID for your field.
- }
- You should keep the field's methods that are required for it to operate in
- database migrations such as ``__init__()``, ``deconstruct()``, and
- ``get_internal_type()``. Keep this stub field for as long as any migrations
- which reference the field exist. For example, after squashing migrations and
- removing the old ones, you should be able to remove the field completely.
- .. _data-migrations:
- Data Migrations
- ---------------
- As well as changing the database schema, you can also use migrations to change
- the data in the database itself, in conjunction with the schema if you want.
- Migrations that alter data are usually called "data migrations"; they're best
- written as separate migrations, sitting alongside your schema migrations.
- Django can't automatically generate data migrations for you, as it does with
- schema migrations, but it's not very hard to write them. Migration files in
- Django are made up of :doc:`Operations </ref/migration-operations>`, and
- the main operation you use for data migrations is
- :class:`~django.db.migrations.operations.RunPython`.
- To start, make an empty migration file you can work from (Django will put
- the file in the right place, suggest a name, and add dependencies for you)::
- python manage.py makemigrations --empty yourappname
- Then, open up the file; it should look something like this::
- # -*- coding: utf-8 -*-
- from django.db import models, migrations
- class Migration(migrations.Migration):
- dependencies = [
- ('yourappname', '0001_initial'),
- ]
- operations = [
- ]
- Now, all you need to do is create a new function and have
- :class:`~django.db.migrations.operations.RunPython` use it.
- :class:`~django.db.migrations.operations.RunPython` expects a callable as its argument
- which takes two arguments - the first is an :doc:`app registry
- </ref/applications/>` that has the historical versions of all your models
- loaded into it to match where in your history the migration sits, and the
- second is a :doc:`SchemaEditor </ref/schema-editor>`, which you can use to
- manually effect database schema changes (but beware, doing this can confuse
- the migration autodetector!)
- Let's write a simple migration that populates our new ``name`` field with the
- combined values of ``first_name`` and ``last_name`` (we've come to our senses
- and realized that not everyone has first and last names). All we
- need to do is use the historical model and iterate over the rows::
- # -*- coding: utf-8 -*-
- from django.db import models, migrations
- def combine_names(apps, schema_editor):
- # We can't import the Person model directly as it may be a newer
- # version than this migration expects. We use the historical version.
- Person = apps.get_model("yourappname", "Person")
- for person in Person.objects.all():
- person.name = "%s %s" % (person.first_name, person.last_name)
- person.save()
- class Migration(migrations.Migration):
- dependencies = [
- ('yourappname', '0001_initial'),
- ]
- operations = [
- migrations.RunPython(combine_names),
- ]
- Once that's done, we can just run ``python manage.py migrate`` as normal and
- the data migration will run in place alongside other migrations.
- You can pass a second callable to
- :class:`~django.db.migrations.operations.RunPython` to run whatever logic you
- want executed when migrating backwards. If this callable is omitted, migrating
- backwards will raise an exception.
- .. _data-migrations-and-multiple-databases:
- Data migrations and multiple databases
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- When using multiple databases, you may need to figure out whether or not to
- run a migration against a particular database. For example, you may want to
- **only** run a migration on a particular database.
- In order to do that you can check the database connection's alias inside a
- ``RunPython`` operation by looking at the ``schema_editor.connection.alias``
- attribute::
- from django.db import migrations
- def forwards(apps, schema_editor):
- if not schema_editor.connection.alias == 'default':
- return
- # Your migration code goes here
- class Migration(migrations.Migration):
- dependencies = [
- # Dependencies to other migrations
- ]
- operations = [
- migrations.RunPython(forwards),
- ]
- .. versionadded:: 1.8
- You can also provide hints that will be passed to the :meth:`allow_migrate()`
- method of database routers as ``**hints``:
- .. snippet::
- :filename: myapp/dbrouters.py
- class MyRouter(object):
- def allow_migrate(self, db, model, **hints):
- if 'target_db' in hints:
- return db == hints['target_db']
- return True
- Then, to leverage this in your migrations, do the following::
- from django.db import migrations
- def forwards(apps, schema_editor):
- # Your migration code goes here
- class Migration(migrations.Migration):
- dependencies = [
- # Dependencies to other migrations
- ]
- operations = [
- migrations.RunPython(forwards, hints={'target_db': 'default'}),
- ]
- More advanced migrations
- ~~~~~~~~~~~~~~~~~~~~~~~~
- If you're interested in the more advanced migration operations, or want
- to be able to write your own, see the :doc:`migration operations reference
- </ref/migration-operations>`.
- .. _migration-squashing:
- Squashing migrations
- --------------------
- You are encouraged to make migrations freely and not worry about how many you
- have; the migration code is optimized to deal with hundreds at a time without
- much slowdown. However, eventually you will want to move back from having
- several hundred migrations to just a few, and that's where squashing comes in.
- Squashing is the act of reducing an existing set of many migrations down to
- one (or sometimes a few) migrations which still represent the same changes.
- Django does this by taking all of your existing migrations, extracting their
- ``Operation``\s and putting them all in sequence, and then running an optimizer
- over them to try and reduce the length of the list - for example, it knows
- that :class:`~django.db.migrations.operations.CreateModel` and
- :class:`~django.db.migrations.operations.DeleteModel` cancel each other out,
- and it knows that :class:`~django.db.migrations.operations.AddField` can be
- rolled into :class:`~django.db.migrations.operations.CreateModel`.
- Once the operation sequence has been reduced as much as possible - the amount
- possible depends on how closely intertwined your models are and if you have
- any :class:`~django.db.migrations.operations.RunSQL`
- or :class:`~django.db.migrations.operations.RunPython` operations (which can't
- be optimized through) - Django will then write it back out into a new set of
- initial migration files.
- These files are marked to say they replace the previously-squashed migrations,
- so they can coexist with the old migration files, and Django will intelligently
- switch between them depending where you are in the history. If you're still
- part-way through the set of migrations that you squashed, it will keep using
- them until it hits the end and then switch to the squashed history, while new
- installs will just use the new squashed migration and skip all the old ones.
- This enables you to squash and not mess up systems currently in production
- that aren't fully up-to-date yet. The recommended process is to squash, keeping
- the old files, commit and release, wait until all systems are upgraded with
- the new release (or if you're a third-party project, just ensure your users
- upgrade releases in order without skipping any), and then remove the old files,
- commit and do a second release.
- The command that backs all this is :djadmin:`squashmigrations` - just pass
- it the app label and migration name you want to squash up to, and it'll get to
- work::
- $ ./manage.py squashmigrations myapp 0004
- Will squash the following migrations:
- - 0001_initial
- - 0002_some_change
- - 0003_another_change
- - 0004_undo_something
- Do you wish to proceed? [yN] y
- Optimizing...
- Optimized from 12 operations to 7 operations.
- Created new squashed migration /home/andrew/Programs/DjangoTest/test/migrations/0001_squashed_0004_undo_somthing.py
- You should commit this migration but leave the old ones in place;
- the new migration will be used for new installs. Once you are sure
- all instances of the codebase have applied the migrations you squashed,
- you can delete them.
- Note that model interdependencies in Django can get very complex, and squashing
- may result in migrations that do not run; either mis-optimized (in which case
- you can try again with ``--no-optimize``, though you should also report an issue),
- or with a ``CircularDependencyError``, in which case you can manually resolve it.
- To manually resolve a ``CircularDependencyError``, break out one of
- the ForeignKeys in the circular dependency loop into a separate
- migration, and move the dependency on the other app with it. If you're unsure,
- see how makemigrations deals with the problem when asked to create brand
- new migrations from your models. In a future release of Django, squashmigrations
- will be updated to attempt to resolve these errors itself.
- Once you've squashed your migration, you should then commit it alongside the
- migrations it replaces and distribute this change to all running instances
- of your application, making sure that they run ``migrate`` to store the change
- in their database.
- After this has been done, you must then transition the squashed migration to
- a normal initial migration, by:
- - Deleting all the migration files it replaces
- - Removing the ``replaces`` argument in the ``Migration`` class of the
- squashed migration (this is how Django tells that it is a squashed migration)
- .. note::
- Once you've squashed a migration, you should not then re-squash that squashed
- migration until you have fully transitioned it to a normal migration.
- .. _migration-serializing:
- Serializing values
- ------------------
- Migrations are just Python files containing the old definitions of your models
- - thus, to write them, Django must take the current state of your models and
- serialize them out into a file.
- While Django can serialize most things, there are some things that we just
- can't serialize out into a valid Python representation - there's no Python
- standard for how a value can be turned back into code (``repr()`` only works
- for basic values, and doesn't specify import paths).
- Django can serialize the following:
- - ``int``, ``long``, ``float``, ``bool``, ``str``, ``unicode``, ``bytes``, ``None``
- - ``list``, ``set``, ``tuple``, ``dict``
- - ``datetime.date``, ``datetime.time``, and ``datetime.datetime`` instances
- (include those that are timezone-aware)
- - ``decimal.Decimal`` instances
- - Any Django field
- - Any function or method reference (e.g. ``datetime.datetime.today``) (must be in module's top-level scope)
- - Any class reference (must be in module's top-level scope)
- - Anything with a custom ``deconstruct()`` method (:ref:`see below <custom-deconstruct-method>`)
- .. versionchanged:: 1.7.1
- Support for serializing timezone-aware datetimes was added.
- Django can serialize the following on Python 3 only:
- - Unbound methods used from within the class body (see below)
- Django cannot serialize:
- - Nested classes
- - Arbitrary class instances (e.g. ``MyClass(4.3, 5.7)``)
- - Lambdas
- Due to the fact ``__qualname__`` was only introduced in Python 3, Django can only
- serialize the following pattern (an unbound method used within the class body)
- on Python 3, and will fail to serialize a reference to it on Python 2::
- class MyModel(models.Model):
- def upload_to(self):
- return "something dynamic"
- my_file = models.FileField(upload_to=upload_to)
- If you are using Python 2, we recommend you move your methods for upload_to
- and similar arguments that accept callables (e.g. ``default``) to live in
- the main module body, rather than the class body.
- .. _custom-deconstruct-method:
- Adding a deconstruct() method
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- You can let Django serialize your own custom class instances by giving the class
- a ``deconstruct()`` method. It takes no arguments, and should return a tuple
- of three things ``(path, args, kwargs)``:
- * ``path`` should be the Python path to the class, with the class name included
- as the last part (for example, ``myapp.custom_things.MyClass``). If your
- class is not available at the top level of a module it is not serializable.
- * ``args`` should be a list of positional arguments to pass to your class'
- ``__init__`` method. Everything in this list should itself be serializable.
- * ``kwargs`` should be a dict of keyword arguments to pass to your class'
- ``__init__`` method. Every value should itself be serializable.
- .. note::
- This return value is different from the ``deconstruct()`` method
- :ref:`for custom fields <custom-field-deconstruct-method>` which returns a
- tuple of four items.
- Django will write out the value as an instantiation of your class with the
- given arguments, similar to the way it writes out references to Django fields.
- To prevent a new migration from being created each time
- :djadmin:`makemigrations` is run, you should also add a ``__eq__()`` method to
- the decorated class. This function will be called by Django's migration
- framework to detect changes between states.
- As long as all of the arguments to your class' constructor are themselves
- serializable, you can use the ``@deconstructible`` class decorator from
- ``django.utils.deconstruct`` to add the ``deconstruct()`` method::
- from django.utils.deconstruct import deconstructible
- @deconstructible
- class MyCustomClass(object):
- def __init__(self, foo=1):
- self.foo = foo
- ...
- def __eq__(self, other):
- return self.foo == other.foo
- The decorator adds logic to capture and preserve the arguments on their
- way into your constructor, and then returns those arguments exactly when
- deconstruct() is called.
- Supporting Python 2 and 3
- -------------------------
- In order to generate migrations that support both Python 2 and 3, all string
- literals used in your models and fields (e.g. ``verbose_name``,
- ``related_name``, etc.), must be consistently either bytestrings or text
- (unicode) strings in both Python 2 and 3 (rather than bytes in Python 2 and
- text in Python 3, the default situation for unmarked string literals.)
- Otherwise running :djadmin:`makemigrations` under Python 3 will generate
- spurious new migrations to convert all these string attributes to text.
- The easiest way to achieve this is to follow the advice in Django's
- :doc:`Python 3 porting guide </topics/python3>` and make sure that all your
- modules begin with ``from __future__ import unicode_literals``, so that all
- unmarked string literals are always unicode, regardless of Python version. When
- you add this to an app with existing migrations generated on Python 2, your
- next run of :djadmin:`makemigrations` on Python 3 will likely generate many
- changes as it converts all the bytestring attributes to text strings; this is
- normal and should only happen once.
- .. _upgrading-from-south:
- Upgrading from South
- --------------------
- If you already have pre-existing migrations created with
- `South <http://south.aeracode.org>`_, then the upgrade process to use
- ``django.db.migrations`` is quite simple:
- * Ensure all installs are fully up-to-date with their migrations.
- * Remove ``'south'`` from :setting:`INSTALLED_APPS`.
- * Delete all your (numbered) migration files, but not the directory or
- ``__init__.py`` - make sure you remove the ``.pyc`` files too.
- * Run ``python manage.py makemigrations``. Django should see the empty
- migration directories and make new initial migrations in the new format.
- * Run ``python manage.py migrate``. Django will see that the tables for the
- initial migrations already exist and mark them as applied without running
- them.
- That's it! The only complication is if you have a circular dependency loop
- of foreign keys; in this case, ``makemigrations`` might make more than one
- initial migration, and you'll need to mark them all as applied using::
- python manage.py migrate --fake yourappnamehere
- Libraries/Third-party Apps
- ~~~~~~~~~~~~~~~~~~~~~~~~~~
- If you are a library or app maintainer, and wish to support both South migrations
- (for Django 1.6 and below) and Django migrations (for 1.7 and above) you should
- keep two parallel migration sets in your app, one in each format.
- To aid in this, South 1.0 will automatically look for South-format migrations
- in a ``south_migrations`` directory first, before looking in ``migrations``,
- meaning that users' projects will transparently use the correct set as long
- as you put your South migrations in the ``south_migrations`` directory and
- your Django migrations in the ``migrations`` directory.
- More information is available in the
- `South 1.0 release notes <http://south.readthedocs.org/en/latest/releasenotes/1.0.html#library-migration-path>`_.
- .. seealso::
- :doc:`The Migrations Operations Reference </ref/migration-operations>`
- Covers the schema operations API, special operations, and writing your
- own operations.
|