Django使用migrations命令继续为旧数据库重新创建外键字段

2024-06-17 11:59:08 发布

您现在位置:Python中文网/ 问答频道 /正文

我对Django开发公司很陌生。我正在使用MySQL创建的遗留数据库。现在我面临着Django迁移的问题。我有几个表使用外键引用另一个表。现在,如果我允许Django使用外键管理这些表,那么Django会在makemigrations和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:\Users\Usama\dev\Django Projects\lib\site-packages\MySQLdb\connections.py", line 259, in query
    _mysql.connection.query(self, query)
django.db.utils.OperationalError: (1060, "Duplicate column name 'brand_id'")

现在我知道Django正在尝试重新创建外键字段。但由于它是一个遗留数据库,我无法理解为什么会发生这种情况


Tags: djangonamefromimport数据库truedbmodels
2条回答

今天我遇到了这个问题,当时我不得不使用Django 1.11对一个非常遗留的项目进行一个小的更改。我相信你遇到了this bug。在comment 7中提到的解决办法对我很有效。这个bug还没有解决,所以它可能仍然会出现在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

根据文档here,您需要告诉django不要管理您的模型。设置 managed=False,如果您不希望django在迁移过程中创建或修改任何内容

相关问题 更多 >