Добавление поля в модель 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'", потому что он пытается создать его. Есть ли способ обойти это?

Что я пробовал:

  1. Добавьте поле с новым столбцом и сделайте миграцию для этого:

        age = models.IntegerField(db_column="age_2")
    
  2. Создайте ручную миграцию данных для копирования данных из исходного столбца в новый:
    UPDATE person SET age_2 = age;

  3. Создайте ручную миграцию для удаления исходного столбца:
    ALTER TABLE person DROP COLUMN age;

  4. Создайте ручную миграцию для переименования нового столбца:
    ALTER TABLE person CHANGE COLUMN age_2 age INT(11) NOT NULL;

  5. В модели измените ее для использования колонки age (db_column="age") и сделайте автоматическую миграцию.

Это работает на моей существующей базе данных, но когда я запускаю тесты, и он применяет все миграции для создания тестовой базы данных, он жалуется на Unknown column 'age' in 'field list' (без указания, какая миграция вызывает это).

Я нашел а решение, но оно кажется настолько трудоемким и халтурным, что я очень надеюсь, что есть лучший способ. Но, это работает как для кода с существующей унаследованной базой данных (которая уже имеет age столбец), так и при выполнении тестов, которые начинаются с создания свежей базы данных.

Я думаю, что лучший способ, который вы ищете, это:

  1. Добавьте поле возраст в модель Django;
  2. Сгенерируйте миграцию с помощью makemigrations;
  3. Вместо обычного запуска миграции, запустите migrate с параметром --fake.

Это говорит Django, что миграция уже была применена к базе данных (поскольку колонка уже существует), и поэтому он должен просто отметить миграцию как примененную.

Вернуться на верх