简体   繁体   English

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

[英]Django migrations foreign key mismatch with legacy database

Hej all,嘿嘿,

I am trying to integrate a SQLite legacy database with Django v3.1.2, and so far it's pretty painful (new to django, so apologies if it's sth obvious).我正在尝试将 SQLite 旧数据库与 Django v3.1.2 集成,到目前为止它非常痛苦(django 的新手,如果它很明显,请道歉)。 I assume something is wrong with my database schema or with the migration process.我认为我的数据库架构或迁移过程有问题。 So here is what I did and my problem:所以这是我所做的和我的问题:

I have run inspectdb on my legacy database and cleaned up the models, leaving me with the following two models (there are more models in my application, but these are the ones apparently causing a problem):我已经在我的旧数据库上运行了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'

The respective fields in my legacy database are:我的旧数据库中的相应字段是:

Integrons: arg_id, int_id, int_start, int_stop, int_complete IntElements: int_id, el_id, el_start, el-stop, el_name, el_strand积分:arg_id、int_id、int_start、int_stop、int_complete IntElements:int_id、el_id、el_start、el-stop、el_name、el_strand

As seen in the models, IntElements.int_id should refer to Integrons.int_id.从模型中可以看出,IntElements.int_id 应指代 Integrons.int_id。

Now I am trying to migrate everything - running python manage.py makemigrations works fine.现在我正在尝试迁移所有内容 - 运行python manage.py makemigrations工作正常。 However, when running python manage.py migrate , I get the following error:但是,在运行python manage.py migrate ,出现以下错误:

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

I don't understand what the problem is.我不明白问题是什么。 The first time I ran this I thought the problem was my model order, as I had defined IntElements before Integrons in models.py.我第一次跑这一点,我认为这个问题是我的模型秩序,因为我已经定义IntElements之前Integrons在models.py。 I changed it, deleted the .pyc files in the migration folder and repeated the migration process, getting the same error.我更改了它,删除了迁移文件夹中的.pyc文件并重复了迁移过程,得到了同样的错误。 When I delete the migration files and comment out the IntElements model in models.py and run makemigrations , I see that all models except IntElements are created.当我删除迁移文件并注释掉 models.py 中的IntElements模型并运行makemigrations ,我看到除IntElements之外的所有模型都已创建。 But when I then run python manage.py migrate , I get the same error, which leads me to believe that something is going wrong with the migration process.但是当我然后运行python manage.py migrate ,我得到了同样的错误,这让我相信迁移过程出了问题。 Or could it be the _id in my column names?或者它可能是我列名中的 _id 吗?

Would really apprechiate any help on this!真的会对此有任何帮助!

EDIT _____编辑_____

python manage.py showmigrations

outputs产出

    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

Something is amiss here, because unmanaged models do not create migrations :这里有些不对劲,因为非托管模型 不会创建迁移

By default, inspectdb creates unmanaged models.默认情况下,inspectdb 创建非托管模型。 That is, managed = False in the model's Meta class tells Django not to manage each table's creation, modification, and deletion即模型的 Meta 类中的 managed = False 告诉 Django 不要管理每个表的创建、修改和删除

[code sample cut] [代码示例剪切]

If you do want to allow Django to manage the table's lifecycle, you'll need to change the managed option above to True (or remove it because True is its default value).如果您确实想让 Django 管理表的生命周期,则需要将上面的 managed 选项更改为 True(或将其删除,因为 True 是其默认值)。

This is intentional as the most prominent case of legacy databases are read-only databases that provide information that is being phased out.这是有意为之,因为遗留数据库最突出的情况是只读数据库,它提供正在逐步淘汰的信息。 Using Django to manage them would disrupt the legacy application and may not even be possible if proper permissions are set for schema operations.使用 Django 来管理它们会破坏遗留应用程序,如果为模式操作设置了适当的权限,甚至可能无法实现。

You also mention tables are being created which again conflicts with unmanaged tables.您还提到正在创建的表再次与非托管表冲突。

If your goal is to import the schema, then delete the SQLite database and have it properly populated and managed by Django, then you must make the models managed by deleting managed = False from the model Meta class.如果您的目标是导入架构,然后删除 SQLite 数据库并由 Django 正确填充和管理它,那么您必须通过从模型元类中删除managed = Falsemanaged = False模型。 This is the other common use case in which you inherit a database and want to start from that and move forward using the migration framework.这是您继承数据库并希望从该数据库开始并使用迁移框架继续前进的另一个常见用例。 Inspectdb is a one-off command then to have your boilerplate in place. Inspectdb 是一个一次性命令,可以让您的样板文件就位。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM