Композитные OneToOneFields в Джанго - PullRequest
2 голосов
/ 15 сентября 2011

Я довольно новичок в Django, и я думаю, что в значительной степени понимаю основную идею ORM.Однако есть особая ситуация, в которой я не вижу вероятного решения.У меня есть устаревшая база данных, для которой я пытаюсь написать приложение Django.Структура sql обеих таблиц:

mysql> describe event;
+-----------+------------------+------+-----+---------+-------+
| Field     | Type             | Null | Key | Default | Extra |
+-----------+------------------+------+-----+---------+-------+
| sid       | int(10) unsigned | NO   | PRI | NULL    |       | 
| cid       | int(10) unsigned | NO   | PRI | NULL    |       | 
| signature | int(10) unsigned | NO   | MUL | NULL    |       | 
| timestamp | datetime         | NO   | MUL | NULL    |       | 
+-----------+------------------+------+-----+---------+-------+
mysql> describe alerts;
+----------------+-----------+------+-----+-------------------+----------------+
| Field          | Type      | Null | Key | Default           | Extra          |
+----------------+-----------+------+-----+-------------------+----------------+
| id             | int(11)   | NO   | PRI | NULL              | auto_increment | 
| sid            | int(11)   | YES  | MUL | NULL              |                | 
| cid            | int(11)   | YES  |     | NULL              |                | 
| confidence     | int(11)   | YES  |     | NULL              |                | 
| cvss_base      | float     | YES  |     | NULL              |                | 
| composite_conf | float     | YES  |     | NULL              |                | 
+----------------+-----------+------+-----+-------------------+----------------+

Первая таблица не может быть изменена, потому что это может привести к поломке большого количества кода (который я не написал).Вторая таблица была написана мной (следовательно, суррогатным ключом). Во второй таблице («алерты») (sid, cid) уникальна.

Проблема в том, что ключ (sid, cid) является ключевымна какие таблицы можно эффективно соединить.Как следует переписать модели, чтобы Django мог точно отразить связь между двумя таблицами?Я пробовал OnetoOne для sid и cid отдельно, но это явно бесполезно, поскольку OnetoOne должен применяться одновременно к (sid, cid).OnetoMany также бесполезен и не является ForeignKey, так как мне нужно (sid, cid) быть внешним ключом.Похоже, что составное поле (sid, cid) должно быть OnetoOne, но я не знаю, как этого добиться.

Примечание - значение (sid, cid) будет иметь тип 1-55,2-55, 3-55,1-56,2-57,3-60 и т. Д., Все они уникальны и будут иметь только одну запись в обеих таблицах.

Позднее редактирование: Я думаю, Django не поддерживает Compositeключи onetoone (по крайней мере, так сказал один из ребят из Google-группы).Я перешел на SQLalchemy, и он представляет модель именно так, как я хочу (составные ключи и т. Д.)

1 Ответ

0 голосов
/ 15 сентября 2011

Django сейчас не поддерживает составной первичный ключ (: _ (я знаю ...), но он работает. В настоящее время вы можете объявить один из sid или cid как primarykey=True и использовать unique_together=('sid','cid') для принудительного применения составного первичного ключа в модели * 1007. * Теперь о sid и cid модели alert по умолчанию django рассматривает модель pk из event дляотношения, но вы можете использовать атрибут to_field с отношением onetoone, чтобы указывать на определенные поля. Таким образом, ваша результирующая модель будет выглядеть так:

class Event(Model):
      sid = Model.IntegerField(primary_key=True,..) #primary_key = True
      cid = Model.IntegerField(...) #don't assign primary_key = True
      ....
      class Meta:
            db_table = u"event"
            unique_together = ("sid","cid") #enforces them to be unique :)

class Alert(Model):
      sid = Model.OneToOneField(Event,to_field='sid'...) #POINT! to sid of event model  
      cid = Model.OneToOneField(Event,to_field='cid'...) #POINT! to cid of event model
      ....
...