如何设置主键,然后转换为autofield?

mli*_*ner 7 django postgresql django-south

我有一个名为的模型Document,我想添加一个新表,DocumentCluster它位于它上面,带有一个外键Document.

class DocumentCluster(models.Model):
    sub_document = models.ForeignKey(Document)
    ...lots of fields here...
Run Code Online (Sandbox Code Playgroud)

当我使用South添加此表时,我需要通过将主键和外键设置为相同的值来填充它.

例如,如果我现在有一个Document与对象pk12,新的DocumentCluster对象将有一个pk12的和一个外键Document12号.

虽然我们需要DocumentCluster pk值来匹配外键值似乎很奇怪,但有一个重要原因.我们Document pk在URL中使用,但在更改后,URL将加载a DocumentCluster而不是a Document,因此我们将需要pkin DocumentCluster与其中的相同Document.

一旦完成,我希望它的PK DocumentCluster是一个AutoField,从迁移的最高值开始递增.

可以这样做吗?

Erw*_*ter 1

您不能在拥有 FK from DocumentCluster.pk Document的同时创建DocumentCluster.pk专栏serial。这是一个矛盾。它必须是两个单独的列。我想你的意思是相反的: Document DocumentCluster

这可以通过 SQL DDL 命令来完成:

BEGIN;

CREATE TABLE DocumentCluster (pk serial, lots text, of_fields int, ...);

INSERT INTO DocumentCluster (pk, lots, of_fields, ...)
SELECT pk, lots, of_fields, ... FROM Document
ORDER  BY pk; -- optional

ALTER TABLE DocumentCluster ADD CONSTRAINT DocumentCluster_pkey
PRIMARY KEY (pk);  -- could be integrated in CREATE TABLE

ALTER TABLE Document  -- and not the other way round!
ADD   CONSTRAINT pk_fk FOREIGN KEY (pk) REFERENCES DocumentCluster(pk);

SELECT setval(pg_get_serial_sequence('DocumentCluster', 'pk'), max(pk))
FROM   DocumentCluster;  -- update SEQUENCE to highest value

COMMIT;
Run Code Online (Sandbox Code Playgroud)
  • 您的混淆层(Django)可能使用双引号名称,例如"Document",在这种情况下您必须执行相同的操作...

  • 关于setval()

  • 关于pg_get_serial_sequence()

  • PK 可以在CREATE TABLE语句中声明,但在插入行之后添加它会更便宜 - 假设pkunique not null

更多解释和链接:


归档时间:

查看次数:

592 次

最近记录:

10 年,6 月 前