Django迁移外键与旧数据库不匹配

时间:2020-10-29 10:10:51

标签: python django django-models django-migrations legacy-database

嘿,所有

我正在尝试将SQLite旧式数据库与Django v3.1.2集成在一起,到目前为止,这是很痛苦的(django的新功能,很抱歉,因此深表歉意)。我认为我的数据库架构或迁移过程出了点问题。所以这就是我所做的和我的问题:

我已经在旧数据库上运行inspectdb并清理了模型,剩下以下两个模型(我的应用程序中有更多模型,但是这些显然引起了问题):

class Integrons(models.Model):
    arg = models.ForeignKey('Args', on_delete=models.CASCADE)
    int_id = models.IntegerField(primary_key=True)
    int_start = models.IntegerField()
    int_stop = models.IntegerField()
    int_complete = models.CharField(max_length=500)

    class Meta:
        managed = False
        db_table = 'integrons'

class IntElements(models.Model):
    int = models.ForeignKey('Integrons', on_delete=models.CASCADE)
    el_id = models.IntegerField()
    el_start = models.IntegerField()
    el_stop = models.IntegerField()
    el_name = models.CharField(blank=True, null=True, max_length=500)
    el_strand = models.CharField(blank=True, null=True, max_length=500)

    class Meta:
        managed = False
        db_table = 'int_elements'

我的旧数据库中的各个字段是:

整数:arg_id,int_id,int_start,int_stop,int_complete IntElements:int_id,el_id,el_start,el-stop,el_name,el_strand

从模型中可以看出,IntElements.int_id应该引用Integrons.int_id。

现在,我正在尝试迁移所有内容-运行python manage.py makemigrations可以正常工作。 但是,在运行python manage.py migrate时,出现以下错误:

django.db.migrations.exceptions.MigrationSchemaMissing: Unable to create the django_migrations table (foreign key mismatch - "int_elements" referencing "integrons")

我不明白问题是什么。第一次执行此操作时,我认为问题出在我的模型顺序上,因为我在models.py中的IntElements之前定义了Integrons。我进行了更改,删除了迁移文件夹中的.pyc文件,然后重复了迁移过程,并得到了相同的错误。当我删除迁移文件并在models.py中注释掉IntElements模型并运行makemigrations时,我看到创建了除IntElements以外的所有模型。但是,当我随后运行python manage.py migrate时,我遇到了同样的错误,这使我相信迁移过程出了点问题。还是我列名中的_id?

真的很感谢您的帮助!

编辑 > _____

python manage.py showmigrations

输出

    python manage.py showmigrations
System check identified some issues:

WARNINGS:
db_app.Lineages.taxon: (fields.W342) Setting unique=True on a ForeignKey has the same effect as using a OneToOneField.
    HINT: ForeignKey(unique=True) is usually better served by a OneToOneField.
admin
 [ ] 0001_initial
 [ ] 0002_logentry_remove_auto_add
 [ ] 0003_logentry_add_action_flag_choices
auth
 [ ] 0001_initial
 [ ] 0002_alter_permission_name_max_length
 [ ] 0003_alter_user_email_max_length
 [ ] 0004_alter_user_username_opts
 [ ] 0005_alter_user_last_login_null
 [ ] 0006_require_contenttypes_0002
 [ ] 0007_alter_validators_add_error_messages
 [ ] 0008_alter_user_username_max_length
 [ ] 0009_alter_user_last_name_max_length
 [ ] 0010_alter_group_name_max_length
 [ ] 0011_update_proxy_permissions
 [ ] 0012_alter_user_first_name_max_length
contenttypes
 [ ] 0001_initial
 [ ] 0002_remove_content_type_name
db_app
 [ ] 0001_initial
sessions
 [ ] 0001_initial

1 个答案:

答案 0 :(得分:1)

这里不对,因为非托管模型do not create migrations

默认情况下,inspectdb创建非托管模型。也就是说,模型的Meta类中的managed = False告诉Django不要管理每个表的创建,修改和删除

[代码样本剪切]

如果您确实希望允许Django管理表的生命周期,则需要将上方的托管选项更改为True(或将其删除,因为True是其默认值)。

这是有意为之的,因为遗留数据库最突出的情况是只读数据库,它提供正在逐步淘汰的信息。使用Django来管理它们会破坏原有的应用程序,而且即使为架构操作设置了适当的权限也可能无法实现。

您还提到正在创建表,该表又与非托管表冲突。

如果您的目标是导入模式,然后删除SQLite数据库并由Django正确填充和管理它,那么您必须通过从模型Meta类中删除managed = False来管理模型。这是另一个常见用例,您可以继承数据库,并希望从数据库开始并使用迁移框架继续前进。 Inspectdb是一个一次性命令,然后将样板放置到位。

相关问题