2

我对 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              |                | 
+----------------+-----------+------+-----+-------------------+----------------+

第一个表不能更改,因为它会破坏很多代码(我没有写)。第二个表是我写的(因此是代理键)。在第二个('alerts')表中,(sid,cid)是唯一的。

问题是 (sid,cid) 是可以有效连接表的关键。应该如何重写模型,以便 Django 可以准确地捕获两个表之间的关系?我分别为 sid 和 cid 尝试了 OnetoOne,但这显然没有用,因为 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-group 中的一个人所说的)。我迁移到 SQLalchemy,它完全按照我想要的方式表示模型(复合键等)

4

1 回答 1

0

Django 目前不支持复合主键( :_( i'know.. ),但它正在开发中。暂时您可以声明其中一个sidor cidasprimarykey=True并使用 unique_together=('sid','cid')强制模型中的复合主键event。现在关于alert模型的sidcid默认情况下django考虑模型pkevent关系,但你可以使用关系 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
      ....
于 2011-09-15T17:05:02.073 回答