Добавление поля в модель Django, когда колонка уже существует в базе данных
У меня есть модель в Django, которая представляет таблицу MySQL, имеющую несколько дополнительных столбцов. Я хочу добавить в модель поле для одного из этих дополнительных столбцов, но я не уверен, как лучше это сделать.
Допустим, в таблице person
есть столбец age
. Моя модель выглядит следующим образом:
class Person(models.Model):
name = models.CharField(min_length=200)
Если я добавляю поле возраста, например:
age = models.IntegerField(db_column="age")
Затем при миграции я получаю ошибку "Duplicate column name 'age'", потому что он пытается создать его. Есть ли способ обойти это?
Что я пробовал:
Добавьте поле с новым столбцом и сделайте миграцию для этого:
age = models.IntegerField(db_column="age_2")
Создайте ручную миграцию данных для копирования данных из исходного столбца в новый:
UPDATE person SET age_2 = age;
Создайте ручную миграцию для удаления исходного столбца:
ALTER TABLE person DROP COLUMN age;
Создайте ручную миграцию для переименования нового столбца:
ALTER TABLE person CHANGE COLUMN age_2 age INT(11) NOT NULL;
В модели измените ее для использования колонки
age
(db_column="age"
) и сделайте автоматическую миграцию.
Это работает на моей существующей базе данных, но когда я запускаю тесты, и он применяет все миграции для создания тестовой базы данных, он жалуется на Unknown column 'age' in 'field list'
(без указания, какая миграция вызывает это).
Я нашел а решение, но оно кажется настолько трудоемким и халтурным, что я очень надеюсь, что есть лучший способ. Но, это работает как для кода с существующей унаследованной базой данных (которая уже имеет age
столбец), так и при выполнении тестов, которые начинаются с создания свежей базы данных.
Я думаю, что лучший способ, который вы ищете, это:
- Добавьте поле возраст в модель Django;
- Сгенерируйте миграцию с помощью
makemigrations
; - Вместо обычного запуска миграции, запустите
migrate
с параметром--fake
.
Это говорит Django, что миграция уже была применена к базе данных (поскольку колонка уже существует), и поэтому он должен просто отметить миграцию как примененную.