【问题标题】:ForeignKey Relationships and Migrating Database in DjangoDjango 中的外键关系和迁移数据库
【发布时间】:2011-11-30 04:57:42
【问题描述】:

我正在使用这两个(示例)模型开发一个 django 项目:

Tenant: id, Building(ForeignKey), User(ForeignKey), NameOfTenant(CharacterField)

Building: id, Address(CharacterField), DateWhenItWasBuild(Date)

我现在基本上打算做的是让一栋建筑物有多个公寓,并将租户与公寓而不是建筑物相关联。因此,我现在计划迁移到以下三种模型:

Tenant: id, Aparment(ForeignKey), User(ForeignKey), NameOfTenant(CharacterField)

Apartment: id, Building(ForeignKey), RoomNumber(Interger), Address(CharacterField)

Building: id, DateWhenItWasBuild(Date)

首先,我添加了公寓模型/表格,并使用建筑物表中的信息(地址和建筑物外键)填充它。其次,我将公寓的外键字段添加到租户模型中。

如果我现在想将租户表中的公寓 ID 引用到公寓(反过来又引用建筑物),我会得到一个外键约束异常:

(1452, 'Cannot add or update a child row: a foreign key constraint fails
(`database`.`tenant_tenant`, CONSTRAINT `apartment_id_refs_id_5dfbfc78bb68defd`
FOREIGN KEY (`apartment_id`) REFERENCES `property_apartment` (`id`))')

我不太确定为什么会发生这种情况,但我怀疑以下可能导致问题: 租户有一个建筑外键和一个公寓外键。但是,公寓也有建筑的外键。

在下一步中,我会将租户中的引用添加到公寓,然后删除对建筑物的引用。这里的问题是我不能先删除建筑物参考然后添加公寓参考,因为我会丢失租户居住的建筑物/公寓的信息。

有谁知道这是问题所在还是我只是错过了一些完全不同的东西?

【问题讨论】:

    标签: sql django migration foreign-keys constraints


    【解决方案1】:

    第一种方法:

    您可以创建树形表,并在迁移完成后将rename tables 原名:

    Create table new_building ( id, DateWhenItWasBuild(Date) );
    insert into new_building ( id, DateWhenItWasBuil ) 
    select ( id, DateWhenItWasBuil )  from building;
    
    Create table Apartment (id, Building(ForeignKey), 
    RoomNumber(Interger), Address(CharacterField) ;
    
    insert into Apartment (id, Building(ForeignKey), 
    RoomNumber(Interger), Address(CharacterField) )
    select id, id, NULL, Address from building;
    
    create table new_Tenant( id, Aparment(ForeignKey), 
    User(ForeignKey), NameOfTenant(CharacterField) );
    
    insert into new_Tenant ( id, Aparment, 
    User, NameOfTenant ) 
    select id, building, user, nameofTenant)
    

    然后删除旧表并重命名新闻:

    DROP TABEL Tenant;
    DROP TABLE building;
    RENAME TABLE new_Tenant TO Tenant
        , new_building TO building;
    

    我假设此时 apparmentId 是 buildingId。但是您可以从另一个表中获取此值。

    请记住,手动创建表不是强制性的。您可以在 meta 中重命名表名并使用 syncdb 创建表:

    class Tenant(models.Model):    
        # ...
        class Meta:
            db_Table = 'new_tenant'
    

    此外,您可以在不删除外键字段的情况下删除外键约束。

    [ALTER TABLE tenant_tenant DROP FOREIGN KEY apartment_id_refs_id_5dfbfc78bb68defd;][2]
    

    请记住,south 可以在这个问题上为您提供帮助。

    【讨论】:

    • 我试图找出为什么会发生这种情况,似乎上面描述的关系问题不是原因。
    猜你喜欢
    • 2019-08-11
    • 1970-01-01
    • 1970-01-01
    • 2019-07-12
    • 2021-02-11
    • 2016-09-24
    • 2015-03-02
    • 2014-02-21
    • 2017-08-26
    相关资源
    最近更新 更多