Django продолжает воссоздавать поле внешнего ключа для устаревшей базы данных с помощью команды миграции

#python #mysql #django #django-models #legacy-database

#python #mysql #django #django-models #устаревшая база данных

Вопрос:

Я совсем новичок в разработке Django. Я работаю с устаревшей базой данных, созданной с помощью MySQL. Теперь я сталкиваюсь с проблемами с миграциями Django. У меня есть несколько таблиц, которые используют внешние ключи для ссылки на другую таблицу. Теперь, если я разрешаю Django управлять этими таблицами с помощью внешних ключей, то Django пытается воссоздать поля внешнего ключа во время выполнения миграций и команды migrate. Даже когда поля уже есть. Кроме того, этот Django отлично работает с базой данных, если я не разрешаю Django управлять этими таблицами.

Мой код предназначен для ошибки, связанной с таблицей

Models.py

 from django.db import models
from django.utils.translation import gettext_lazy as _
from django.db.models.signals import pre_save
from chooseright.utils import unique_slug_generator

class StoreTable(models.Model):
    store_id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=45, blank=True, null=True)
    slug = models.SlugField(max_length=45, blank=True, null=True)
    category = models.ForeignKey(CategoryTable, on_delete=models.CASCADE, blank=True, null=True)
    brand = models.ForeignKey(BrandTable, models.DO_NOTHING, blank=True, null=True)
    
    class Meta:
        managed = True
        db_table = 'store_table'
        verbose_name = _("Store")
        verbose_name_plural = _("Stores")

    def __str__(self):
        return self.name
  

Код миграции

 from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

    dependencies = [
        ('core', '0009_auto_20200820_1258'),
    ]

    operations = [
        migrations.RenameField(
            model_name='storetable',
            old_name='store_name',
            new_name='name',
        ),
        migrations.AddField(
            model_name='storetable',
            name='brand',
            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, to='core.BrandTable'),
        ),
        migrations.AddField(
            model_name='storetable',
            name='category',
            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='core.CategoryTable'),
        ),
    ]
  

Обратная трассировка при попытке миграции

   File "C:UsersUsamadevDjango Projectslibsite-packagesMySQLdbconnections.py", line 259, in query
    _mysql.connection.query(self, query)
django.db.utils.OperationalError: (1060, "Duplicate column name 'brand_id'")
  

Теперь я знаю, что Django пытается воссоздать поле внешнего ключа. Но поскольку это устаревшая база данных, я не могу понять, почему это происходит.

Комментарии:

1. Итак, я просто попытался удалить поле для внешнего ключа из модели, и это не привело к удалению исходного поля из базы данных. Ничего, если я продолжу это.

Ответ №1:

Я столкнулся с этой проблемой сегодня, когда мне пришлось внести небольшие изменения в действительно устаревший проект, используя Django 1.11. Я полагаю, что вы столкнулись с этой ошибкой. Обходной путь, упомянутый в комментарии 7, сработал для меня. Ошибка еще не устранена, поэтому, возможно, она все еще происходит в более новых версиях Django.

По сути, вы бы выполнили эти шаги, чтобы обойти проблему:

  1. При первоначальном запуске inspectdb и для создания модели Django создаст модель с помощью managed = False .
  2. В models.py вы должны временно установить managed = True перед выполнением миграции.
  3. Затем создайте миграции с помощью manage.py makemigrations . Пока не запускайте миграцию.
  4. Проверьте сгенерированный файл миграции и вручную обновите все managed: True до manage: False .
  5. Наконец, вернитесь к своему models.py и верните любое managed = True значение managed = False .
  6. Теперь запустите миграцию с помощью manage.py migrate .

После выполнения вышеуказанных шагов вам следует преобразовать неуправляемые модели в управляемые, выполнив следующее:

  1. В models.py теперь вы будете постоянно устанавливать managed = True или просто удалять managed строку в целом, как по умолчанию True .
  2. Создайте миграции с помощью manage.py makemigrations .
  3. Запустите миграции с помощью manage.py migrate .

На этом этапе вы можете вносить дальнейшие обновления в модель, и вы заметите, что Django больше не пытается воссоздать ForeignKey то, что уже существует.

Комментарии:

1. Спасибо за ваш ответ.

Ответ №2:

Согласно приведенным здесь документам, вам нужно сказать django, чтобы он не управлял вашей моделью. Установите managed=False вашей модели, если вы не хотите, чтобы django создавал или изменял что-либо своими миграциями.

Комментарии:

1. Я проверил это. Но я хочу изменить таблицы для своей работы.