2

当我检查 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 但ticket_changeTrac 中的原始主键是:

Primary key (ticket, time, field)

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

如果我time像 pk 一样定义,我不能同时添加两个票证更改。

我能做些什么?

4

3 回答 3

1

你是对的。这是一个已知问题。所以唯一的解决方案是黑客(有点)。

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

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

对不起,我没有更好的解决方案给你,就是这样。Legacy dbs 和 django 总是让人头疼,自己也经历过一些类似的过程。希望这可以帮助!

于 2013-11-15T11:35:33.230 回答
0

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

ticket_change = TicketChange.objects.get(ticket=1234, time=5678, field='myfield')
于 2013-11-15T11:38:43.527 回答
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

于 2020-10-02T12:21:10.250 回答