Российский Новый Университет
Опубликован: 25.01.2016 | Доступ: свободный | Студентов: 2235 / 161 | Длительность: 16:40:00
Лекция 11:

Подключение к базе данных

Файл миграции

Итак, что же содержит файл миграции, и что действительно происходит при выполнении команды:

python manage.py migrate tweet

После ее выполнения, вы можете увидеть каталог migrations, где хранятся файлы миграции. Давайте взглянем на них.. так как это файлы Python, то их можно легко понять.

Откройте файл tweet/migrations/0001_initial.py, так как это файл, где создан код первоначальной миграции. Он должен выглядеть примерно так:

# -*- coding: utf-8 -*-
from  future  import unicode_literals
from django.db import models, migrations
class Migration(migrations.Migration): dependencies = [
('user_profile',	'first'),
]
operations = [
migrations.CreateModel( name='HashTag', fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('name', models.CharField(unique=True, max_length=64)),
3,
options = {
},
bases=(models.Model,),
) ,
migrations.CreateModel( name='Tweet', fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('text', models.CharField(max_length=160)),
('created_date', models.DateTimeField(auto_now_add=True)),
('country', models.CharField(default=b'Global', max_length=30)),
('is_active', models.BooleanField(default=True)),
('user', models.ForeignKey(to='user_profile.User')),
] ,
options = {
},
bases=(models.Model, ) ,
) ,
migrations.AddField( model_name='hashtag' , name='tweet',
field=models.ManyToManyField(to='tweet.Tweet'),preserve_default=True,
) ,
}

Для того, чтобы миграция действительно работала, здесь должен быть класс Migration () который наследует от модуля django.db.migrations.Migration. Это основной класс, который используют инструменты миграции, и этот класс миграции содержит два основных списка:

  • Зависимости: Это список других миграций, которые должны быть выполнены перед тем, как эта миграция запустится. В случаях, где есть зависимость, таких как, отношения с внешним ключом, модель внешнего ключа должна существовать прежде самого ключа. В предыдущем случае мы имеет такую зависимость в виде параметра user_profile.
  • Операции: Этот список содержит список миграций, которые должны быть применены, и операция миграции может относиться к одной из следующих категорий:
    • CreateModel: Как понятно из имени, очевидно, что эта операция создает новую модель. В предудущем файле модели вы можете видеть такие строки:
      migrations.CreateModel ( 
      name='HashTag',……
      migrations.CreateModel(
      name='Tweet',……..
      

      Эти строки миграции создают новую модель с определенными атрибутами.

    • DeleteModel: Содержит операторы для удаления модели из базы данных. Противоположно методу CreateModel.
    • RenameModel: Переименовывает модель и дает новое имя взамен старого.
    • AlterModelTable: Изменяет имя связанной с моделью таблицы.
    • AlterUniqueTogether: Уникально ограничивает таблицу, которая изменилась.
    • AltelndexTogether: Изменяет пользовательский набор индексов модели.
    • AddField: Просто добавляет поле к существующей модели.
    • RemoveField: Удаляет поле из модели.
    • RenameField: Переименовывает поле и дает новое имя взамен старого.

Схема миграции – не единственное, что требуется для миграции при обновлении приложения; Другой важной вещью являются данные миграции.

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

Данные миграции могут быть использованы во многих ситуациях. Среди них большинство логических ситуаций, таких как:

  • Загрузка внешних данных в приложение
  • Когда есть изменение в схеме модели и набор данных нужно обновить

Давайте поиграем с нашим проектом, загрузив твит из файла username.txt. Создайте пустую миграцию для нашего проекта, используя следующую команду:

python manage.py makemigrations --empty tweet

Это создаст файл миграции mytweets/migrations/003_auto<date_ time_stamp>.py.

Открыв этот файл, он будет выглядеть следующим образом:

# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models, migrations


class Migration(migrations.Migration):

    dependencies = [
        ('tweets', '0002_auto_20150926_1834'),
    ]

    operations = [
    ]

Здесь нет ничего, кроме основной структуры инструмента миграции Django, и чтобы организовать миграцию данных, мы должны добавить функцию RunPython () — в операции, как показано:

#	 -*- coding: utf-8 -*-
from  future  import unicode_literals
from django.db import models, migrations
def load_data(apps, schema_editor):
Tweet(text= 'This is sample Tweet', created_date=date(2013,11,29), country='India', is_active=True,
) .save () 
class Migration(migrations.Migration):
dependencies = [
('tweet',	'0002_auto_20141215_0808 ' ),
]
operations = [
migrations.RunPython(load_data)
]

Теперь выполним команду migrate:

python manage.py migrate

Вот операции, которые вам необходимо выполнить:

Synchronize unmigrated apps: userprofile
Apply all migrations: admin, contenttypes, tweet, auth, sessions Synchronizing apps without migrations:
Creating tables...
Installing custom SQL...
Installing indexes...
Running migrations:
Applying contenttypes.000linitial... FAKED
 Applying auth.0001initial... FAKED 
Applying admin.0001initial... FAKED 
Applying sessions.0001_initial... FAKED
 Applying tweet.0003_auto_20141215_1349 ... OK

После выполнения предыдущей команды, команда мигрировала все приложения и в наконец применила нашу миграцию, в которой мы создали новый твит из загруженных данных:

mysql> select * from tweettweet;
+	+	+	+	
| id | user_id | text | created_date | country | is_active |
+	+	+	+	
| 1 | 1 | This Tweet was uploaded from the file. | 2014-12-15 14:17:42 | India | 1 |
+-----+---------+-------------------------------------------+---------
2 rows in set (0.00 sec)

Невероятно, правда?

Этот типа решения очень необходим, когда у вас есть внешние данные в форме JSON или XML-файла.

Идеальным решением будет использовать аргумент командной строки, чтобы получить путь к файлу и загрузить данные в виде:

python load data tweet/initial_data.json

Не забудьте добавить ваши каталоги миграции на Git, так как они так же важны, как и ваш исходный код.

Константин Боталов
Константин Боталов

Вроде легкие вопросы и ответы знаю правильные, но система считает иначе и правильные ответысчитает неправильными. Приходится выполнть по несколько раз. Это я не правильно делаю или тест так составлен?

Владимир Филипенко
Владимир Филипенко

Листинг показывает в 4-ой лекции, что установлен Django 1.8.4. Тут же далее в этой лекции указаны настройки, которые воспринимает Django 1.7 и младше.