Статья: Data Migrations (Перенос Данных).

Оглавление:

Миграции в основном предназначены для поддержания актуальной модели данных вашей базы данных, но база данных - это нечто большее, чем просто модель данных. Самое примечательное, это большой набор данных. Таким образом, любое обсуждение миграции базы данных было бы неполным, если бы мы не говорили о миграции данных.
Итак, что же такое "Перенос данных"?

Определение миграции (переноса) данных

Миграция или перенос данных используется в ряде сценариев. Два очень популярных из них:

  1. Когда вы хотите загрузить "системные данные", от наличия которых зависит успешная работа вашего приложения.
  2. Когда изменение модели данных вызывает необходимость изменения существующих данных.

Примеры

Продолжая предыдущий проект Django, в качестве примера создания «системных данных» давайте создадим некоторые исторические цены на биткойны. Миграции Django помогут нам, создав пустой файл миграции и поместив его в нужное место, если мы введем:

$ ./manage.py makemigrations --empty historical_data

Это должно создать файл с именем historical_data/migrations/003_auto<date_time_stamp>.py. Давайте изменим имя на 003_load_historical_data.pyи откроем его. У вас будет структура по умолчанию, которая выглядит так:

# encoding: utf8
from django.db import models, migrations


class Migration(migrations.Migration):

    dependencies = [
        ('historical_data', '0002_auto_20140710_0810'),
    ]

    operations = [
    ]

Вы можете видеть, что он создал для нас базовую структуру и даже вставил зависимости. Это полезно. Теперь, чтобы выполнить миграцию данных, используйте RunPython операцию миграции:

# encoding: utf8
from django.db import models, migrations
from datetime import date

def load_data(apps, schema_editor):
    PriceHistory = apps.get_model("historical_data", "PriceHistory")

    PriceHistory(date=date(2013,11,29),
         price=1234.00,
         volume=354564,
         total_btc=12054375,
         ).save()
    PriceHistory(date=date(2012,11,29),
         price=12.15,
         volume=187947,
         total_btc=10504650,
         ).save()


class Migration(migrations.Migration):

    dependencies = [
        ('historical_data', '0002_auto_20140710_0810'),
    ]

    operations = [
        migrations.RunPython(load_data)
    ]

Мы начинаем с определения функции, load_dataкоторая, как вы уже догадались, загружает данные.

Когда у нас есть функция, мы можем вызвать ее из нашей RunPythonоперации, а затем эта функция будет выполняться при запуске ./manage.py migrateиз командной строки.

Обратите внимание на строку:

PriceHistory = apps.get_model("historical_data", "PriceHistory")

При выполнении миграции важно получить версию нашей PriceHistoryмодели, которая соответствует точке миграции, в которой вы находитесь. По мере выполнения миграции ваша модель ( PriceHistory) может измениться, если, например, вы добавите или удалите столбец в последующей миграции. Это может привести к сбою миграции данных, если вы не используете приведенную выше строку для получения правильной версии модели.

Это, возможно, больше работы, чем запуск syncdbи загрузка прибора. Фактически, миграции не принимают во внимание фикстуры - это означает, что они не загружают их автоматически, как syncdbхотелось бы.

В основном это связано с философией.

Хотя вы можете использовать миграции для загрузки данных, они в основном касаются миграции данных и / или моделей данных. Мы показали пример загрузки системных данных, главным образом потому, что это простое объяснение того, как вы должны настроить миграцию данных, но часто миграции данных используются для более сложных действий, таких как преобразование ваших данных в соответствии с новой моделью данных.

Например, если бы мы решили начать хранить цены с нескольких бирж, а не только с одной, чтобы мы могли добавлять такие поля, как price_goxprice_btcи т. Д., Тогда мы могли бы использовать миграцию для перемещения всех данных из priceстолбца в price_btcстолбец.

В целом, имея дело с миграциями в Django 1.7, лучше всего рассматривать загрузку данных как отдельное упражнение от миграции базы данных. Если вы хотите продолжать использовать / загружать приборы, вы можете использовать такую ​​команду, как:

$ ./manage.py loaddata historical_data/fixtures/initial_data.json

Это загрузит данные из прибора в базу данных.

Это не происходит автоматически, как при переносе данных (что, вероятно, хорошо), но функциональность все еще есть; он не утерян, поэтому не стесняйтесь и дальше использовать приспособления, если в этом есть необходимость. Разница в том, что теперь вы загружаете данные с приборами, когда они вам нужны. Об этом следует помнить, если вы используете фикстуры для загрузки тестовых данных для своих модульных тестов .

 

Заключение

В ней, наряду с двумя предыдущими статьями, рассматриваются наиболее распространенные сценарии, с которыми вы можете столкнуться при использовании миграции. Есть еще много сценариев, и если вам интересно и действительно хотите погрузиться в миграцию, лучше всего (кроме самого кода) обратиться к официальной документации .

Он самый современный и довольно хорошо объясняет, как все работает. Если есть более сложный сценарий, пример которого вы хотели бы увидеть, сообщите нам об этом, оставив комментарий ниже.

Помните, что в общем случае вы имеете дело либо с:

  1. Миграция схемы: изменение структуры базы данных или таблиц без изменения данных. Это наиболее распространенный тип, и Django обычно может создавать эти миграции автоматически.
  2. Перенос данных: изменение данных или загрузка новых данных. Django не может их сгенерировать. Их необходимо создать вручную с помощью RunPythonмиграции.

Так что выберите миграцию, которая вам подходит, запустите, makemigrationsа затем обязательно обновляйте файлы миграции каждый раз, когда вы обновляете свою модель - и это более или менее. Это позволит вам сохранить ваши миграции с вашим кодом в git и гарантировать, что вы можете обновить структуру базы данных без потери данных.

Удачной миграции!

Оригинал статьи: https://realpython.com/data-migrations/

 

Один комментарий

Оставьте ответ

Ваш адрес email не будет опубликован. Обязательные поля помечены *