【问题标题】:Django keeps migrating the same foreign keyDjango 不断迁移相同的外键
【发布时间】:2019-03-22 05:29:48
【问题描述】:

我正在将现有数据库导入到它自己的 Django 项目中。我已经通过inspectdb 从数据库中生成了初始模型,并且通过注释表元设置中的managed=False 行,使 Django 能够一次控制每个表。我从简单的模型开始,在启用带有外键的表时遇到了麻烦。 Django 不断为外键 DocTagID 生成相同的迁移,我不确定它为什么会这样做?

有问题的表格如下所示,所有内容均由inspectdb 生成,但注释行除外,这是我将表格的控制权传递给 Django。

class Doctagversion(models.Model):
    id = models.IntegerField(db_column='Id', primary_key=True, blank=True)  # Field name made lowercase.
    doctagid = models.ForeignKey(DocTag, models.DO_NOTHING, db_column='DocTagId')  # Field name made lowercase.
    groupname = models.TextField(db_column='GroupName')  # Field name made lowercase.
    name = models.TextField(db_column='Name')  # Field name made lowercase.
    creationdate = models.DateTimeField(db_column='CreationDate')  # Field name made lowercase.
    lasteditdate = models.DateTimeField(db_column='LastEditDate', blank=True, null=True)  # Field name made lowercase.
    lastedituserid = models.IntegerField(db_column='LastEditUserId')  # Field name made lowercase.
    lastedituserdisplayname = models.TextField(db_column='LastEditUserDisplayName')  # Field name made lowercase.
    releasedate = models.DateTimeField(db_column='ReleaseDate', blank=True, null=True)  # Field name made lowercase.

    class Meta:
#         managed = False
        db_table = 'DocTagVersion'

在传递此控件之前,使用python -m manage.py makemigrations 生成相关架构的初始迁移,并使用python -m manage.py migrate 应用。表的初始迁移如下,managed 最初设置为False,注释行是我相信我应该添加以通知 Django 外键的条目(inspectdb 在生成的@ 987654332@).

    migrations.CreateModel(
        name='Doctagversion',
        fields=[
            ('id', models.IntegerField(blank=True, db_column='Id', primary_key=True, serialize=False)),
            # ('doctagid',models.ForeignKey(db_column='DocTagId', default=-1, on_delete=models.deletion.DO_NOTHING, to='DocTag')),
            ('groupname', models.TextField(db_column='GroupName')),
            ('name', models.TextField(db_column='Name')),
            ('creationdate', models.DateTimeField(db_column='CreationDate')),
            ('lasteditdate', models.DateTimeField(blank=True, db_column='LastEditDate', null=True)),
            ('lastedituserid', models.IntegerField(db_column='LastEditUserId')),
            ('lastedituserdisplayname', models.TextField(db_column='LastEditUserDisplayName')),
            ('releasedate', models.DateTimeField(blank=True, db_column='ReleaseDate', null=True)),
        ],
        options={
            'db_table': 'DocTagVersion',
            'managed': False,
        },
    ),

当我启用对表的控制时,第一次迁移只会更改表选项。

    migrations.AlterModelOptions(
        name='doctagversion',
        options={},
    ),

如果初始迁移中不存在相关外键,Django 会添加该外键,如下所示。

    migrations.AddField(
        model_name='doctagversion',
        name='doctagid',
        field=models.ForeignKey(db_column='DocTagId', default=-1, on_delete=django.db.models.deletion.DO_NOTHING, to='docutoo.DocTag'),
        preserve_default=False,
    ),

此后,它在python m manage.py makemigrationspython -m manage.py migrate 之间重复生成以下迁移。

    migrations.AlterField(
        model_name='doctagversion',
        name='doctagid',
        field=models.ForeignKey(db_column='DocTagId', on_delete=django.db.models.deletion.DO_NOTHING, to='docutoo.DocTag'),
    ),

也许我的策略是错误的,我应该在一次迁移中启用所有表?

据我所知,以下相关问题与我的情况无关:

【问题讨论】:

    标签: django inspectdb


    【解决方案1】:

    Bug Report 看来,Django 迁移对命名非常敏感,我在所有模型中都注释掉了 db_table。我相信我是在创建初始迁移后无意中破坏了后来的迁移之后这样做的。

      class Meta : 
        ...
    #     db_table = "TableName"
    

    因为我打破了命名makemigrations 看不到表名已经改变,所以最好通过重复声明字段来解决它。

    一边

    巧合的是,当有人按照我的问题 (inspectdb -> makemigrations -> migrate) 中的描述为现有数据库创建初始迁移时,Django 会按字母顺序遍历模型,以相同的顺序创建表并忽略外国的键。它按字母顺序创建表,然后稍后对其进行修改以包含外键,从而破坏现有数据库中可能存在的任何数据。似乎必须首先将外键定义为整数字段,然后将它们改回来,因为让 Django 管理表。或者,可以注释掉他们的所有模型并生成迁移,因为一个人以一种解析外键的方式取消它们;然后 Django 将相应地链接它们。然后可以将迁移压缩成一个迁移并将其设置为初始迁移。

    【讨论】:

      猜你喜欢
      • 2014-02-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-30
      • 2015-02-19
      • 2016-11-13
      • 2012-04-11
      • 2021-02-11
      相关资源
      最近更新 更多