我正在为我工作的公司开发一个内部应用程序,并且我想使用Django来学习它和Python一般,但是我对PK有点麻烦。 / p>
我正在尝试模拟当前应用程序的一部分,其中2个MySQL表,TaskCategory和Tasks,处理需要执行的任务。每个任务都属于TaskCategory,TaskCategory中的每个项目都有自己独立的递增编号。因此,如果“Office”有15个任务,向其添加另一个任务将使其Task.taskid = 16,但向“车辆”添加任务将使Tasks.taskid = 51,而不是17.然后将其用作跟踪号码,例如Vehicles-51任务。
通过在taskcategoryid和taskid(自动递增)组成的Tasks中包含复合主键来实现这种单独的增量。顺便说一下,Tasks.taskcategoryid不是FK(我不认为它可以是,因为它是复合PK的一部分)。
由于Django不喜欢超过1个PK列,因此我在复制此功能时遇到了一些困难。我尝试过unique_together taskid(自动递增PK)和taskcategoryid(FK),我尝试过2个自动递增列(id和taskid)但你不能有多个自动递增列。
使用Django可以实现这种递增功能吗?我宁愿这样做而不必破解源代码,但如果需要的话也会这样做。
答案 0 :(得分:1)
你的目标是什么?
如果您正在尝试保持与旧应用程序的字段到字段表兼容性,那么您将遇到问题,因为(正如您所观察到的)Django没有compound/composite keys - 它真的喜欢surrogate key。鉴于Django允许的操作以及当前对“正确”数据库设计的思考,代理键是有意义的。
如果您真正想要做的就是保持大多数查询相同(或大部分相似),那么您可以单独保留现有的自然/复合键字段,但删除旧的主键约束,添加新的Django的代理键,然后将Meta data添加到模型中,以声明构成旧复合键的字段为unique_together
。 Django将解释它并添加适当的唯一索引。您需要为对象创建添加一些代码来处理递增/分配TaskCategory
ID,但最终结果是Django和数据库强制执行所有旧关系。
作为一个例子,这是我在一个桌面游戏锦标赛中跟踪玩家的应用程序模型的一部分:
class Player(models.Model):
badge = models.IntegerField()
name = models.CharField( max_length = 99 )
class Round(models.Model):
name = models.CharField( max_length = 9 )
number = models.IntegerField()
class Table(models.Model):
round = models.ForeignKey( Round )
number = models.IntegerField( 'table number')
class Meta:
unique_together = ( 'round', 'number' )
class Seat(models.Model):
table = models.ForeignKey( Table )
position = models.IntegerField( 'seat number' )
player = models.ForeignKey( Player )
class Meta:
unique_together = ( 'table', 'seat' )
在这种情况下,我使用unique_together来确保表格号码在不同轮次中重复使用,并且座位位置在各个表格中相同,您将永远不会遇到相同的圆形,表格和座位组合一次。