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



Hej all,

我正在尝试将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 _completeIntElements: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?

我真的很感激在这方面的任何帮助!

编辑/strong>

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

这里有些问题,因为非托管模型不创建迁移:

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

【代码样本剪切】

如果您确实想让Django管理表的生命周期,您需要将上面的托管选项更改为True(或者删除它,因为True是它的默认值(。

这是有意的,因为遗留数据库最突出的情况是只读数据库,它提供的信息正在逐步淘汰。使用Django来管理它们会破坏遗留应用程序,如果为模式操作设置了适当的权限,甚至可能不可能。

您还提到正在创建的表与非托管表再次发生冲突。

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

最新更新