Django中的ForeignKey关系和迁移数据库

时间:2011-11-30 04:57:43

标签: sql django migration foreign-keys constraints

我正在研究这两个(模范)模型的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`))')

我不太清楚为什么会这样,但我怀疑以下可能导致问题: Tentant拥有建筑物的外键和公寓的外键。但是,公寓也有建造外键。

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

有没有人知道这是问题,还是我错过了一些完全不同的东西?

1 个答案:

答案 0 :(得分: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可以帮助您解决此问题。