Django Custom主键

时间:2013-11-15 10:56:54

标签: python django primary-key composite-primary-key

当我检查Trac数据库时,我得到:

class TicketChange(models.Model):
    ticket = models.IntegerField()
    time = models.BigIntegerField()
    author = models.TextField(blank=True)
    field = models.TextField()
    oldvalue = models.TextField(blank=True)
    newvalue = models.TextField(blank=True)
    class Meta:
        managed = False
        db_table = 'ticket_change'

没有主键:

>>> TicketChange.objects.all()
DatabaseError: column ticket_change.id does not exist
LINE 1: SELECT "ticket_change"."id", "ticket_change"."ticket", "tick...

因为我需要指定一个pk,但Trac中ticket_change的原始主键是:

Primary key (ticket, time, field)

但在Django中不可能:Django Multi-Column Primary Key Discussion

如果我将time定义为pk,我无法同时添加两张故障单。

我该怎么办?

3 个答案:

答案 0 :(得分:1)

你是对的。这是一个众所周知的问题。所以唯一的解决方案就是黑客(等等)。

您最好的选择是使用django-compositepks。缺点是它并不真正支持模型关系,因此您将无法从composite-pk模型导航到任何关系。但是,看看你的TicketChange模型这似乎不是一个问题(除非你有更多的模型与这个模型有关系)。

另一种选择是手动添加id列(并确保对db应用任何其他更改),从而创建新的单列主键。第三个选项(以及我可能会做的)与上一个选项非常相似但更干净,是从头开始创建一个新数据库,然后通过从现有旧数据库中获取数据来填充脚本。

抱歉,我没有更好的解决方案,就是这样。传统的dbs和django总是很头疼,我自己经历过一些类似的过程。希望这有帮助!

答案 1 :(得分:0)

这是Django ORM根本不支持的用例。如果您能够修改数据库模式,请添加一个另外的列作为Django的主键:带有AUTO_INCREMENT(MySQL)或SERIAL(PostgreSQL)的整数字段。它不应该使用该表来破坏您的其他应用程序,因为插入新记录时它将由您的数据库管理。在通过ORM进行查询时,您仍然可以使用实际的主键:

ticket_change = TicketChange.objects.get(ticket=1234, time=5678, field='myfield')

答案 2 :(得分:0)

如果您想指定自定义主键,请在您的其中一个字段上指定primary_key = True。如果Django看到您已明确设置Field.primary_key,则不会添加自动ID列。 每个模型只需要一个字段即可具有primary_key = True(显式声明或自动添加)。

https://docs.djangoproject.com/en/3.1/topics/db/models/#automatic-primary-key-fields