Прийшов час заглибитись у зміни моделей: як змінювати існуючі структури даних та керувати цими змінами через міграції.
Сьогодні ми навчимося:
- Як вносити зміни в існуючі моделі.
- Як створювати міграції для змін.
- Як застосовувати ці міграції до бази даних.
Зміни у структурах моделей
Коли ти створюєш міграції для змін у моделях, ти фактично ініціюєш процес еволюції структури бази даних. Django піклується про те, щоб перехід між різними версіями моделі був максимально безпечним і плавним.
Приклад: додавання нового поля
Припустимо, у нас є модель Book, яка спочатку виглядає ось так:
# models.py
from django.db import models
class Book(models.Model):
title = models.CharField(max_length=200)
author = models.CharField(max_length=100)
published_date = models.DateField()
Після запуску початкової міграції і застосування її до бази даних, цю структуру ми вже "запечатали". Але через місяць до тебе приходить клієнт і просить додати поле ISBN для обліку номерів книг. Ось що треба зробити:
Відкрити файл
models.pyі додати нове поле.# models.py class Book(models.Model): title = models.CharField(max_length=200) author = models.CharField(max_length=100) published_date = models.DateField() isbn = models.CharField(max_length=13, null=True, blank=True) # Нове полеСтворити міграцію для цієї зміни:
python manage.py makemigrationsЗастосувати міграцію:
python manage.py migrate
Django проаналізує зміни в моделі Book і створить міграційний файл, який додає нове поле isbn у таблицю.
Що відбудеться у базі даних?
Django створить SQL-команду для додавання нового стовпця у таблицю Book. Оскільки ми вказали null=True і blank=True, база даних не вимагатиме обов'язкового заповнення цього поля для вже існуючих записів.
Зміна існуючих полів
Тепер припустимо, що клієнт вирішив, що 13 символів для ISBN не завжди достатньо, і тепер довжина поля має бути 20 символів. Ось як ми це зробимо:
Відкрийте
models.pyі змініть атрибутmax_lengthдля поляisbn:class Book(models.Model): title = models.CharField(max_length=200) author = models.CharField(max_length=100) published_date = models.DateField() isbn = models.CharField(max_length=20, null=True, blank=True) # Зміна довжиниСтворіть міграцію:
python manage.py makemigrationsЗастосуйте зміни:
python manage.py migrate
Django згенерує SQL-запит, який змінює довжину стовпця isbn у базі даних.
Видалення полів
Іноді доводиться видаляти існуючі поля. Давайте видалимо поле published_date (але пам'ятайте, що такі зміни можуть призвести до втрати даних!).
Видаліть поле з моделі:
class Book(models.Model): title = models.CharField(max_length=200) author = models.CharField(max_length=100) isbn = models.CharField(max_length=20, null=True, blank=True)Створіть міграцію:
python manage.py makemigrationsЗастосуйте міграцію:
python manage.py migrate
Django видалить стовпець published_date з таблиці Book. Перед цим переконайтеся, що ви зробили бекап даних з цього стовпця, якщо вони вам знадобляться!
Перейменування полів
Якщо потрібно змінити ім'я поля (наприклад, з isbn на isbn_code), використовуйте той самий механізм:
Перейменуйте поле в моделі:
class Book(models.Model): title = models.CharField(max_length=200) author = models.CharField(max_length=100) isbn_code = models.CharField(max_length=20, null=True, blank=True) # Нове ім'яСтворіть міграцію:
python manage.py makemigrationsЗастосуйте міграцію:
python manage.py migrate
Складні зміни: об'єднання або розділення таблиць
Іноді потрібно розділити одну таблицю (модель) на дві або, навпаки, об'єднати кілька моделей в одну. Це складний процес, який, як правило, вимагає ручного втручання. Django створює міграції, але може також знадобитися написати SQL-запити вручну.
Як працює Django при створенні міграцій?
Міграції у Django працюють на принципі відстеження змін у вашій моделі. Коли ви викликаєте manage.py makemigrations, Django порівнює поточну версію моделей із останньою міграцією, яка була застосована раніше. Потім він генерує новий файл міграції на основі цієї зміни.
Файл міграції виглядає як Python-скрипт і зазвичай знаходиться в папці додатку migrations. Ви можете відкрити його і побачити щось подібне:
# Приклад файлу міграції (auto-generated)
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('books', '0001_initial'), # Залежність від попередньої міграції
]
operations = [
migrations.AddField(
model_name='book',
name='isbn',
field=models.CharField(blank=True, max_length=13, null=True),
),
]
Типові помилки та як їх уникнути
Помилки трапляються, коли:
Ви забули застосувати міграцію. Якщо після
makemigrationsви не виконаєтеmigrate, база даних залишиться в старому стані. Обов'язково застосовуйте міграції!Зміни несумісні. Наприклад, ви вирішили видалити поле, яке було обов'язковим (
null=False) — це викличе проблеми, якщо в таблиці вже є записи. Обов'язково додавайтеdefaultабоnull=Trueперед такими змінами.Ви змінюєте поле, яке пов'язане з ForeignKey. При зміні пов'язаних таблиць використовуйте обережні підходи, пам'ятаючи про пов'язані записи.
Ви випадково змінили вже застосовану міграцію. Ніколи не редагуйте раніше автоматично створені міграції. Це може зламати всю послідовність змін бази даних.
Практичне завдання
- Створіть модель
Authorз полямиname(рядок довжиною до 100 символів) таbirth_date(дата). Проведіть міграцію. - Додайте до моделі
Authorполеnationality(рядок довжиною до 50 символів). Проведіть міграцію для цих змін. - Видаліть поле
birth_dateі проведіть чергову міграцію. - Взаємодійте з моделлю через Django shell, запишіть кілька авторів у базу та перевірте їхні поля.
Вуаля, тепер ви готові сміливо змінювати структури своїх моделей та управляти ними через міграції. Впевнений, що ваш клієнт оцінить гнучкість, з якою ви можете відповідати на його зміни вимог!
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ