Рубрики
Без рубрики

Обнаружение кода, который сломает миграцию Django

Можете ли вы увидеть проблемы с этой миграцией Django? # 0006_populate_has_chickens.py из django.d … Помечено Django, Python, WebDev, CodeQuality.

Можете ли вы увидеть проблемы с этой миграцией Django?

# 0006_populate_has_chickens.py
from django.db import migrations
from territory import models

def forwards(apps, schema_editor):
    for item in in models.ChickenCoopLocations.objects.all():
        item.has_chickens = does_have_chickens(item.pk)
        item.save()

class Migration(migrations.Migration):
    dependencies = [("cases", "0005_auto_does_have_chickens.py")]
    operations = [migrations.RunPython(forwards)]


def does_have_chickens(pk):
    ...

Это верно – никакие обратные миграции не указаны, и напрямую импортируют из Models.py Отказ Давайте углубляем, почему последний плохой для ремонтопригодности.

Не в ногу

Поля в Джанго Models.py должен согласиться с схемой в базе данных. Когда Django выполняет операции по чтению базы данных, он использует форму модели в Models.py Чтобы определить, какие поля к ВЫБРАТЬ и ВСТАВЛЯТЬ . Если Models.py Включает в себя поля, которые еще не в схеме базы данных, база данных бросит ошибку.

Это легко пропущено, если код проверяется во время спешки, потому что когда 0006_populate_has_chickens RAN Эта ошибка не произойдет. Действительно, в этот момент вовремя Models.py делает Согласитесь с схемой, но что происходит, когда через один раз ваш член команды добавляет новое поле в Цыплята ? С этого момента, когда 0006_populate_has_chickens RAN, Models.py У вас будет иметь поле, которое схема базы данных еще не имеет, поэтому миграции потерпят неудачу. Это произойдет при настройке новой базы данных, когда все миграции выполняются с нуля, например, в CI, когда новый разработчик присоединяется к команде, или когда вы заменили свой кирпичный ноутбук.

На будущее

В 0006_populate_has_chickens.py Лучше использовать Apps.get_model , который просит Django построить упрощенную модель, путешествующую временем, чьи поля будут отражать поля в базе данных Даже если Models.py очень выходит из шага с схемой:

# 0006_populate_has_chickens.py
from django.db import migrations

def forwards(apps, schema_editor):
    ChickenCoopLocations = apps.get_model("territory", "ChickenCoopLocations")
    for item in in ChickenCoopLocations.objects.all():
        item.has_chickens = does_have_chickens(item.pk)
        item.save()

class Migration(migrations.Migration):
    dependencies = [("cases", "0005_auto_foo.py")]
    operations = [migrations.RunPython(forwards)]

def does_have_chickens(pk):
    ...

Поэтому непосредственно импортирующие модели в миграциях – Flaky, и в нескольких миграциях время, вероятно, не удастся, потому что во время миграции код в моделях .py не выходит с схемы базы данных: Models.py Может иметь определенное поле, которое еще не существует в базе данных, потому что требуемая миграция еще не работает.

Ваш импорт CodeBase использует живые модели .py в миграциях?

Со временем легко проскользнуть в вашей кодовой базе. Я могу проверить это для вас в django.doctor или может Просмотрите свой GitHUB PRS :

Или попробуйте Рефакторы Django Challenges Отказ

Оригинал: “https://dev.to/djangodoctor/migration-breaking-3cl6”