#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.
По сути, вы бы выполнили эти шаги, чтобы обойти проблему:
- При первоначальном запуске
inspectdb
и для создания модели Django создаст модель с помощьюmanaged = False
. - В
models.py
вы должны временно установитьmanaged = True
перед выполнением миграции. - Затем создайте миграции с помощью
manage.py makemigrations
. Пока не запускайте миграцию. - Проверьте сгенерированный файл миграции и вручную обновите все
managed: True
доmanage: False
. - Наконец, вернитесь к своему
models.py
и верните любоеmanaged = True
значениеmanaged = False
. - Теперь запустите миграцию с помощью
manage.py migrate
.
После выполнения вышеуказанных шагов вам следует преобразовать неуправляемые модели в управляемые, выполнив следующее:
- В
models.py
теперь вы будете постоянно устанавливатьmanaged = True
или просто удалятьmanaged
строку в целом, как по умолчаниюTrue
. - Создайте миграции с помощью
manage.py makemigrations
. - Запустите миграции с помощью
manage.py migrate
.
На этом этапе вы можете вносить дальнейшие обновления в модель, и вы заметите, что Django больше не пытается воссоздать ForeignKey
то, что уже существует.
Комментарии:
1. Спасибо за ваш ответ.
Ответ №2:
Согласно приведенным здесь документам, вам нужно сказать django, чтобы он не управлял вашей моделью. Установите managed=False
вашей модели, если вы не хотите, чтобы django создавал или изменял что-либо своими миграциями.
Комментарии:
1. Я проверил это. Но я хочу изменить таблицы для своей работы.