Вроде легкие вопросы и ответы знаю правильные, но система считает иначе и правильные ответысчитает неправильными. Приходится выполнть по несколько раз. Это я не правильно делаю или тест так составлен? |
Подключение к базе данных
Файл миграции
Итак, что же содержит файл миграции, и что действительно происходит при выполнении команды:
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: Переименовывает поле и дает новое имя взамен старого.
- CreateModel: Как понятно из имени, очевидно, что эта операция создает новую модель. В предудущем файле модели вы можете видеть такие строки:
Схема миграции – не единственное, что требуется для миграции при обновлении приложения; Другой важной вещью являются данные миграции.
Это данные, которые уже хранятся в базе данных в результате предыдущих операций, и так же нуждаются в миграции.
Данные миграции могут быть использованы во многих ситуациях. Среди них большинство логических ситуаций, таких как:
- Загрузка внешних данных в приложение
- Когда есть изменение в схеме модели и набор данных нужно обновить
Давайте поиграем с нашим проектом, загрузив твит из файла 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, так как они так же важны, как и ваш исходный код.