Django                
            Миграции
        
        
            
    Поиск…
параметры
| Команда django-admin | подробности | 
|---|---|
| makemigrations <my_app> | Создание миграции для my_app | 
| makemigrations | Создание миграций для всех приложений | 
| makemigrations --merge | Устранение конфликтов миграции для всех приложений | 
| makemigrations --merge <my_app> | my_appконфликтов миграции дляmy_app | 
| makemigrations --name <migration_name> <my_app> | Сформировать миграции для my_appс именемmigration_name | 
| migrate <my_app> | Применить ожидающие миграции my_appв базу данных | 
| migrate | Применить все ожидающие миграции в базу данных | 
| migrate <my_app> <migration_name> | Применить или исключить до migration_name | 
| migrate <my_app> zero | Не использовать все миграции в my_app | 
| sqlmigrate <my_app> <migration_name> | Распечатывает SQL для указанной миграции | 
| showmigrations | Показывает все миграции для всех приложений | 
| showmigrations <my_app> | Показывает все миграции в my_app | 
Работа с миграциями
Django использует миграции для распространения изменений, которые вы делаете на свои модели, в свою базу данных. В большинстве случаев django может генерировать их для вас.
Чтобы создать миграцию, выполните:
$ django-admin makemigrations <app_name>
 Это создаст файл migration подмодуле migration app_name . Первая миграция будет называться 0001_initial.py , другая начнется с 0002_ , затем 0003 , ... 
 Если вы опустите <app_name> это создаст миграцию для всех ваших INSTALLED_APPS . 
Чтобы распространять миграцию в вашу базу данных, запустите:
$ django-admin migrate <app_name>
Чтобы показать все ваши миграции, запустите:
$ django-admin showmigrations app_name
app_name
  [X] 0001_initial
  [X] 0002_auto_20160115_1027
  [X] 0003_somemodel
  [ ] 0004_auto_20160323_1826
-  [X]означает, что миграция была передана в вашу базу данных
-  [ ]означает, что миграция не была распространена в вашей базе данных. Используйтеdjango-admin migrateдля распространения
 Вы также вызываете и возвращаете миграцию, это можно сделать, передав имя migrate command . Учитывая приведенный выше список миграций (показано с помощью django-admin showmigrations ): 
$ django-admin migrate app_name 0002  # Roll back to migration 0002
$ django-admin showmigrations app_name
app_name
  [X] 0001_initial
  [X] 0002_auto_20160115_1027
  [ ] 0003_somemodel
  [ ] 0004_auto_20160323_1826
Ручная миграция
Иногда миграций, создаваемых Django, недостаточно. Это особенно актуально, если вы хотите выполнить миграцию данных .
Например, давайте иметь такую модель:
class Article(models.Model):
    title = models.CharField(max_length=70)
 У этой модели уже есть существующие данные, и теперь вы хотите добавить SlugField : 
class Article(models.Model):
    title = models.CharField(max_length=70)
    slug = models.SlugField(max_length=70)
 Вы создали миграцию для добавления поля, но теперь вы хотите установить пул для всей существующей статьи в соответствии с их title . 
Конечно, вы можете просто сделать что-то подобное в терминале:
$ django-admin shell
>>> from my_app.models import Article
>>> from django.utils.text import slugify
>>> for article in Article.objects.all():
...     article.slug = slugify(article.title)
...     article.save()
...
>>>
Но вам придется делать это во всех своих средах (например, на рабочем столе вашего офиса, на вашем ноутбуке ...), всем вашим коллегам также придется это делать, и вам придется подумать об этом при постановке и при нажатии жить.
Чтобы сделать это раз и навсегда, мы сделаем это в процессе миграции. Сначала создайте пустую миграцию:
$ django-admin makemigrations --empty app_name
 Это создаст пустой файл миграции. Откройте его, он содержит базовый скелет. Предположим, что ваша предыдущая миграция была названа 0023_article_slug и она называется 0024_auto_20160719_1734 . Вот что мы напишем в нашем файле миграции: 
# -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2016-07-19 15:34
from __future__ import unicode_literals
from django.db import migrations
from django.utils.text import slugify
def gen_slug(apps, schema_editor):
    # We can't import the Article model directly as it may be a newer
    # version than this migration expects. We use the historical version.
    Article = apps.get_model('app_name', 'Article')
    for row in Article.objects.all():
        row.slug = slugify(row.name)
        row.save()
class Migration(migrations.Migration):
    dependencies = [
        ('hosting', '0023_article_slug'),
    ]
    operations = [
        migrations.RunPython(gen_slug, reverse_code=migrations.RunPython.noop),
        # We set `reverse_code` to `noop` because we cannot revert the migration
        # to get it back in the previous state.
        # If `reverse_code` is not given, the migration will not be reversible,
        # which is not the behaviour we expect here.
    ]
Поддельные миграции
Когда миграция выполняется, Django сохраняет имя миграции в таблице django_migrations.
Создание и подделка начальных миграций для существующей схемы
Если ваше приложение уже имеет модели и таблицы базы данных и не имеет миграций. Сначала создайте начальные миграции для своего приложения.
python manage.py makemigrations your_app_label
Теперь поддельные начальные миграции применимы
python manage.py migrate --fake-initial
Поддельные все миграции во всех приложениях
python manage.py migrate --fake
Поддельные миграции приложений
python manage.py migrate --fake core
Поддельный файл с одной миграцией
python manage.py migrate myapp migration_name
Пользовательские имена для файлов миграции
 Используйте параметр makemigrations --name <your_migration_name> чтобы разрешить именовать миграцию (-и) вместо использования сгенерированного имени. 
python manage.py makemigrations --name <your_migration_name> <app_name>
Устранение конфликтов миграции
Вступление
Иногда конфликты конфликтуют, в результате чего миграция не выполняется. Это может произойти во множестве scenerio, однако это может происходить на регулярной основе при разработке одного приложения с командой.
 Общие конфликты миграции происходят при использовании контроля источника, особенно когда используется метод «функция-ветвь». Для этого сценария мы будем использовать модель Reporter с name и address атрибутов. 
 Два разработчика на этом этапе собираются разработать функцию, поэтому они оба получат эту исходную копию модели Reporter . Разработчик A добавляет age который приводит к файлу 0002_reporter_age.py . Разработчик B добавляет поле bank_account которое 0002_reporter_bank_account в 0002_reporter_bank_account . Как только эти разработчики объединит свой код и попытаются перенести миграции, возник конфликт миграции. 
 Этот конфликт возникает, потому что эти миграции изменяют одну и ту же модель, Reporter . Кроме того, новые файлы начинаются с 0002. 
Слияние миграций
Есть несколько способов сделать это. В рекомендуемом порядке:
- Самое простое решение для этого - запустить команду makemigrations с флагом -merge. - python manage.py makemigrations --merge <my_app>- Это создаст новую миграцию, разрешающую предыдущий конфликт. 
- Когда этот дополнительный файл не приветствуется в среде разработки по личным причинам, опция заключается в удалении конфликтующих миграций. Затем новая миграция может быть выполнена с помощью обычной команды - makemigrations. Когда пользовательские миграции записываются, например- migrations.RunPython, необходимо учитывать этот метод.
Измените CharField на ForeignKey
 Прежде всего, давайте предположим, что это ваша первоначальная модель внутри приложения, называемого discography : 
from django.db import models
class Album(models.Model):
    name = models.CharField(max_length=255)
    artist = models.CharField(max_length=255)
Теперь вы понимаете, что вместо этого вы хотите использовать ForeignKey для исполнителя. Это несколько сложный процесс, который необходимо выполнить в несколько этапов.
Шаг 1, добавьте новое поле для ForeignKey, убедившись, что он отмечен как null (обратите внимание, что теперь мы подключаем модель):
from django.db import models
class Album(models.Model):
    name = models.CharField(max_length=255)
    artist = models.CharField(max_length=255)
    artist_link = models.ForeignKey('Artist', null=True)
class Artist(models.Model):
    name = models.CharField(max_length=255)
... и создать миграцию для этого изменения.
./manage.py makemigrations discography
Шаг 2, заполните новое поле. Для этого вам нужно создать пустую миграцию.
./manage.py makemigrations --empty --name transfer_artists discography
 Когда у вас будет эта пустая миграция, вы хотите добавить к ней одну операцию RunPython , чтобы связать ваши записи. В этом случае он может выглядеть примерно так: 
def link_artists(apps, schema_editor):
    Album = apps.get_model('discography', 'Album')
    Artist = apps.get_model('discography', 'Artist')
    for album in Album.objects.all():
        artist, created = Artist.objects.get_or_create(name=album.artist)
        album.artist_link = artist
        album.save()
 Теперь, когда ваши данные будут перенесены в новое поле, вы действительно можете сделать и оставить все как есть, используя новое поле artist_link для всего. Или, если вы хотите немного очистить, вы хотите создать еще две миграции. 
 Для первой миграции вы хотите удалить свое исходное поле, artist . Для вашей второй миграции переименуйте новое поле artist_link в artist . 
Это делается несколькими шагами, чтобы гарантировать, что Django правильно распознает операции.