Python django中的复合主键

Python django中的复合主键,python,django,postgresql,Python,Django,Postgresql,我有一个具有复合主键的遗留db表。我不认为我将能够更改结构以包含代理键,因为有一些编写的代码使用该表。在django中,我不能使用该表,因为它没有主键(非复合键) django型号支持复合主键吗?如果没有,在不改变表格结构的情况下,是否有任何变通方法 另外,我正在使用postgresql。请尝试以下类似代码: class MyTable(models.Model): class Meta: unique_together = (('key1', 'key2'),)

我有一个具有复合主键的遗留db表。我不认为我将能够更改结构以包含代理键,因为有一些编写的代码使用该表。在django中,我不能使用该表,因为它没有主键(非复合键)

django型号支持复合主键吗?如果没有,在不改变表格结构的情况下,是否有任何变通方法


另外,我正在使用postgresql。

请尝试以下类似代码:

class MyTable(models.Model):
    class Meta:
        unique_together = (('key1', 'key2'),)

    key1 = models.IntegerField(primary_key=True)
    key2 = models.IntegerField()
或者,如果只需要唯一的混合字段:

class MyTable(models.Model):
    class Meta:
        unique_together = (('key1', 'key2'),)

    key1 = models.IntegerField()
    key2 = models.IntegerField()

编辑:我想指出,如果有3列,这种方法就有问题。更新查询不起作用,因为它试图更新(将pk字段放在“SET”之后)唯一的字段,并且明显失败。

另一个选项是在模型的
元中设置
managed=False
,然后手动创建表

class MyTable(models.Model):
    foo = models.IntegerField(primary_key=True)
    bar = models.IntegerField()
    baz = models.IntegerField()

    class Meta:
        managed = False
        db_table = 'myapp_mytable'

    def __repr__(self):
        return f'<MyTable: MyTable object ({self.foo}, {self.bar}, {self.baz)>'
它似乎表现正确:

>>> MyTable.objects.create(foo=1, bar=1, baz=1)
<MyTable: MyTable object (1, 1, 1)>

>>> MyTable.objects.create(foo=1, bar=1, baz=2)
<MyTable: MyTable object (1, 1, 2)>

>>> MyTable.objects.create(foo=1, bar=1, baz=2)
django.db.utils.IntegrityError: duplicate key value violates unique constraint "myapp_mytable_pkey"
DETAIL:  Key (foo, bar, baz)=(1, 1, 2) already exists.
MyTable.objects.create(foo=1,bar=1,baz=1) >>>MyTable.objects.create(foo=1,bar=1,baz=2) >>>MyTable.objects.create(foo=1,bar=1,baz=2) django.db.utils.IntegrityError:重复的键值违反唯一约束“myapp\u mytable\u pkey” 详细信息:键(foo、bar、baz)=(1、1、2)已存在。

注意这只在Django 3.x中测试过,所以我不确定它是否在旧版本中工作。

公认的答案是正确的。不过,它有点旧了
unique\u在一起
可能会被弃用以支持。因此,更好的方法是

UniqueConstraint(fields = ['key1', 'key2'], name = 'constraint_name')
我使用了从django AutoField继承的虚拟字段,该字段将多个字段中的值组合成单个JSON dict

这使得这些模型与django管理和基因视图兼容

$pip安装django viewflow--预安装

从viewflow.fields导入CompositeKey
班级座位(型号.型号):
id=CompositeKey(列=[“飞机代码”,“座位号])
飞机代码=models.ForeignKey(
飞机,模型,什么都不做,
db_列=“飞机代码”
)
座椅编号=型号。CharField(最大长度=4)

这使得可以访问元类中的表,

以及
unique\u中的每个元组一起
属性,该属性通过确定的顺序确定这些字段的混合值不得重复。我的意思是,当您创建
key2=models.IntegerField(unique=True)
时,这是否意味着
key2
对于所有值都必须是唯一的,而不仅仅是对于单个
key1
。第二个版本仍然需要一个主键。
unique\u合在一起
related
key2
value to
key1
value。建议编辑如下:我想指出,如果有3列,则此方法存在问题。更新查询不起作用,因为它尝试更新(将pk字段放在“SET”之后)唯一的字段,并且明显失败。是否可以使用此方法将其他模型的座椅作为外部字段?
UniqueConstraint(fields = ['key1', 'key2'], name = 'constraint_name')