简体   繁体   English

Django 自定义主键

[英]Django Custom primary key

When I inspect the Trac database I get:当我检查 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'

With not primary key:没有主键:

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

Because I need to specify a pk but the original primary key of ticket_change in Trac is:因为我需要指定一个pk但是Trac中ticket_change的原始主键是:

Primary key (ticket, time, field)

But It's not possible in Django: Django Multi-Column Primary Key Discussion .但在 Django: Django Multi-Column Primary Key Discussion 中是不可能的。

If I define time like pk I can't add two tickets changes in the same time.如果我像 pk 那样定义time我就不能同时添加两张票变更。

What can I do?我能做什么?

You're right.你是对的。 It's a known problem.这是一个已知的问题。 So the only solutions are hacks (sort of).所以唯一的解决方案是黑客(有点)。

Your best option is to use django-compositepks .您最好的选择是使用django-compositepks The drawbacks are that it doesn't really support model relationships, so you will not be able to navigate to any relationship from your composite-pk model.缺点是它并不真正支持模型关系,因此您将无法从复合 pk 模型导航到任何关系。 However, looking at your TicketChange model this doesn't seem like an issue (unless you have more models with relationships to this one).但是,查看您的 TicketChange 模型,这似乎不是问题(除非您有更多与此模型相关的模型)。

Another option would be to manually add the id column (and make sure to apply any additional changes to the db), thereby creating the new one-column primary key.另一种选择是手动添加 id 列(并确保对数据库应用任何其他更改),从而创建新的单列主键。 A third option (and what I would probably do), pretty similar to the last one but cleaner, would be to create a new database from scratch and then populate it with a script by fetching the data from your existing legacy db.第三个选项(我可能会做的)与上一个选项非常相似但更简洁,是从头开始创建一个新数据库,然后通过从现有旧数据库中获取数据来使用脚本填充它。

Sorry I don't have any better solution for you, that's the way it is.对不起,我没有更好的解决方案给你,就是这样。 Legacy dbs and django are always a headache, have gone through some similar processes myself. Legacy dbs 和 django 一直很头疼,自己也经历过一些类似的过程。 Hope this helps!希望这可以帮助!

This is a use case the Django ORM simply does not support.这是 Django ORM 根本不支持的用例。 If you're able to modify the database schema, add an additional column that will serve as the primary key for Django: An integer field with AUTO_INCREMENT (MySQL) or a SERIAL (PostgreSQL).如果您能够修改数据库架构,请添加一个额外的列作为 Django 的主键:带有 AUTO_INCREMENT (MySQL) 或 SERIAL (PostgreSQL) 的整数字段。 It shouldn't desturb your other applications using the table since it will be managed by your database when new records are inserted.它不应该干扰您使用该表的其他应用程序,因为在插入新记录时它将由您的数据库管理。 You can still use the actual primary key when making queries through the ORM:通过 ORM 进行查询时,您仍然可以使用实际的主键:

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

If you'd like to specify a custom primary key, specify primary_key=True on one of your fields.如果您想指定自定义主键,请在您的字段之一上指定 primary_key=True。 If Django sees you've explicitly set Field.primary_key, it won't add the automatic id column.如果 Django 发现您已明确设置 Field.primary_key,则不会添加自动 id 列。 Each model requires exactly one field to have primary_key=True (either explicitly declared or automatically added).每个模型只需要一个字段来具有 primary_key=True (显式声明或自动添加)。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM