Миграции Django в Python — как использовать
При работе с Django вам не нужно писать SQL для создания новых таблиц или внесения изменений в существующие таблицы в Python. Вместо этого вы используете миграции Django.
Знакомство с командами миграции Django
Миграции Django позволяют вам переносить изменения, вносимые в модели, в базу данных через командную строку.
Django предоставляет вам несколько команд для создания новых миграций на основе изменений, внесенных вами в модель, и применения миграций к базе данных.
Процесс внесения изменений в модели, создания миграций и применения изменений к базе данных выглядит следующим образом:
- Сначала определите новые модели или внесите изменения в существующие модели.
- Во-вторых, выполните новые миграции, выполнив команду makemigrations.
- В-третьих, примените изменения из моделей к базе данных, выполнив команду миграции.
Предположим, что вы определяете модели постов в приложении блога следующим образом:
from django.db import models from django.utils import timezone from django.contrib.auth.models import User class Post(models.Model): title = models.CharField(max_length=120) content = models.TextField() published_at = models.DateTimeField(default=timezone.now) author = models.ForeignKey(User, on_delete=models.CASCADE) def __str__(self): return self.title
и вы можете создать новую миграцию с помощью команды makemigrations:
python manage.py makemigrations
Команда makemigrations сканирует файл models.py, обнаруживает изменения и выполняет соответствующие миграции. Она покажет следующий вывод:
Migrations for 'blog': blog\migrations\0001_initial.py - Create model Post
В фоновом режиме команда создает файл migrations\0001_initial.py.
Чтобы просмотреть SQL-код, который Django выполнит для создания таблицы blog_post в базе данных, используйте команду sqlmigrate:
python manage.py sqlmigrate blog 0001
В этой команде sqlmigrate blog — это имя приложения, а 0001 — номер миграции.
Выведется следующее:
BEGIN; -- -- Create model Post -- CREATE TABLE "blog_post"( "id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "title" varchar(120) NOT NULL, "content" text NOT NULL, "published_at" datetime NOT NULL, "author_id" integer NOT NULL REFERENCES "auth_user"("id") DEFERRABLE INITIALLY DEFERRED ); CREATE INDEX "blog_post_author_id_dd7a8485" ON "blog_post"("author_id"); COMMIT;
Чтобы применить изменения к базе данных, выполните команду миграции:
python manage.py migrate
Будет показан следующий вывод:
Operations to perform: Apply all migrations: admin, auth, blog, contenttypes, sessions Running migrations: Applying contenttypes.0001_initial... OK Applying auth.0001_initial... OK Applying admin.0001_initial... OK Applying admin.0002_logentry_remove_auto_add... OK Applying admin.0003_logentry_add_action_flag_choices... OK Applying contenttypes.0002_remove_content_type_name... OK Applying auth.0002_alter_permission_name_max_length... OK Applying auth.0003_alter_user_email_max_length... OK Applying auth.0004_alter_user_username_opts... OK Applying auth.0005_alter_user_last_login_null... OK Applying auth.0006_require_contenttypes_0002... OK Applying auth.0007_alter_validators_add_error_messages... OK Applying auth.0008_alter_user_username_max_length... OK Applying auth.0009_alter_user_last_name_max_length... OK Applying auth.0010_alter_group_name_max_length... OK Applying auth.0011_update_proxy_permissions... OK Applying auth.0012_alter_user_first_name_max_length... OK Applying blog.0001_initial... OK Applying sessions.0001_initial... OK
Обратите внимание, что помимо применения миграции для модели Post, Django также применил миграции для встроенных моделей, используемых при аутентификации, авторизации, сеансах и т. д.
Если вы выполните команду миграции еще раз и не будет непримененных миграций, команда выведет следующее:
Operations to perform: Apply all migrations: admin, auth, blog, contenttypes, sessions, users Running migrations: No migrations to apply.
Чтобы вывести список миграций проекта и их статус, используйте команду showmigrations:
python manage.py showmigrations
Выход:
admin [X] 0001_initial [X] 0002_logentry_remove_auto_add [X] 0003_logentry_add_action_flag_choices auth [X] 0001_initial [X] 0002_alter_permission_name_max_length [X] 0003_alter_user_email_max_length [X] 0004_alter_user_username_opts [X] 0005_alter_user_last_login_null [X] 0006_require_contenttypes_0002 [X] 0007_alter_validators_add_error_messages [X] 0008_alter_user_username_max_length [X] 0009_alter_user_last_name_max_length [X] 0010_alter_group_name_max_length [X] 0011_update_proxy_permissions [X] 0012_alter_user_first_name_max_length blog [X] 0001_initial contenttypes [X] 0001_initial [X] 0002_remove_content_type_name sessions [X] 0001_initial