kha*_*vah 36 python django postgresql
我有一个遗留的db表,它有复合主键.我不认为我能够更改结构以包含代理键,因为有一些代码使用该表编写.在django中,我不能使用该表,因为它没有主键(非复合).
django模型是否支持复合主键?如果没有,是否有任何解决方法而不改变表的结构?
PS我正在使用postgresql.
M.j*_*vid 48
尝试类似下面的代码:
class MyTable(models.Model):
class Meta:
unique_together = (('key1', 'key2'),)
key1 = models.IntegerField(primary_key=True)
key2 = models.IntegerField()
Run Code Online (Sandbox Code Playgroud)
或者如果您只想要唯一的混合字段:
class MyTable(models.Model):
class Meta:
unique_together = (('key1', 'key2'),)
key1 = models.IntegerField()
key2 = models.IntegerField()
Run Code Online (Sandbox Code Playgroud)
编辑:我想注意,如果有3列,这种方法有问题.更新查询不起作用,因为它尝试更新(在"SET"之后放置pk字段)一起是唯一的字段并且明显失败.
Tec*_*ins 15
接受的答案很好。然而,它有点老了。unique_together
可能会被弃用而支持UniqueConstraint。因此,这样做的更好方法是;
UniqueConstraint(fields = ['key1', 'key2'], name = 'constraint_name')
Run Code Online (Sandbox Code Playgroud)
managed=False
另一种选择是在模型的 中设置Meta
,然后手动创建表。
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)>'
Run Code Online (Sandbox Code Playgroud)
在 postgres shell 中:
CREATE TABLE myapp_mytable (
foo INTEGER NOT NULL,
bar INTEGER NOT NULL,
baz INTEGER NOT NULL,
PRIMARY KEY(foo, bar, baz)
);
Run Code Online (Sandbox Code Playgroud)
它似乎表现正确:
>>> 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.
Run Code Online (Sandbox Code Playgroud)
请注意,这仅在 Django 3.x 中进行了测试,因此我不确定它是否适用于旧版本。
我使用从 django AutoField 继承的虚拟字段解决了这个问题,它将来自多个字段的值组合到单个 JSON dict 中。
这使得这些模型与 django 管理和遗传视图兼容。
$ pip install django-viewflow --pre
from viewflow.fields import CompositeKey
class Seat(models.Model):
id = CompositeKey(columns=['aircraft_code', 'seat_no'])
aircraft_code = models.ForeignKey(
Aircraft, models.DO_NOTHING,
db_column='aircraft_code'
)
seat_no = models.CharField(max_length=4)
Run Code Online (Sandbox Code Playgroud)
这使得访问旧数据库和PostgreSQL TimeScaleDB表成为可能
归档时间: |
|
查看次数: |
35018 次 |
最近记录: |