База данных ForeignKey по связям и миграции в Джанго - PullRequest
0 голосов
/ 30 ноября 2011

Я работаю над проектом 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)

Сначала я добавил модель / таблицу квартиры и заполнил ее информацией из таблицы зданий (адрес и внешний ключ здания). Во-вторых, я добавил поле внешнего ключа для квартиры в модель арендатора.

Если я теперь хочу привязать идентификатор квартиры в таблице арендаторов к квартире (которая, в свою очередь, относится к зданию), я получу исключение ограничения внешнего ключа:

(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`))')

Я не совсем уверен, почему это происходит, но я подозреваю, что это может быть причиной следующих проблем: Арендатор имеет внешний ключ от здания и внешний ключ от квартиры. Однако у квартиры есть и внешний ключ от здания.

На следующем шаге я бы добавил ссылку на арендатора в квартиру, а затем удалил ссылку на здание. Проблема здесь заключается в том, что я не могу сначала удалить ссылку на здание, а затем добавить ссылку на квартиру, потому что я потеряю информацию, в каком здании / квартире проживает арендатор.

У кого-нибудь есть идея, в этом ли проблема или я просто упускаю что-то совершенно другое?

1 Ответ

1 голос
/ 30 ноября 2011

Первый подход:

Вы можете создать дерево новые таблицы и после завершения миграции переименовать таблицы в исходное имя:

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]

Помните, что юг может помочь вам в этом вопросе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...