Django AutoField没有返回新的primary_key

时间:2011-07-21 16:23:02

标签: django postgresql

我们正在处理的Django项目和postgresql数据库存在一个小问题。

我们正在开发的项目是从PHP站点到django站点的站点/数据库转换。所以我们使用inspect db从当前的PHP后端生成模型。

它给了我们这个,我们添加了primary_key和唯一等于True:

class Company(models.Model):
     companyid = models.IntegerField(primary_key=True,unique=True)
     ...
     ...

当我们最终保存新的公司条目时,这似乎不起作用。它将返回一个非空约束错误,因此我们迁移到如下所示的AutoField:

class Company(models.Model):
     companyid = models.AutoField(primary_key=True)
     ...
     ...

这样可以保存公司入境,但问题出在我们

result = form.save()

我们做不到

result.pk or result.companyid

获取数据库中新给定的主键(但我们可以看到它在数据库中被赋予了适当的公司ID。

我们对正在发生的事情感到茫然。任何想法或答案将不胜感激,谢谢!

1 个答案:

答案 0 :(得分:4)

我刚刚遇到了同样的事情,但是在一个有很多历史的项目的django升级期间。多么痛苦......

无论如何,问题似乎是由于django的postgresql后端获取新创建对象的主键的方式:它使用pg_get_serial_sequence来解析表的主键的序列。就我而言,id列未使用serial类型创建,而是使用integer创建,这意味着我的序列未正确连接到table.column。

以下是基于带有create语句的表,您必须根据您的具体情况调整表名,列和序列名称:

CREATE TABLE "mike_test" (
  "id" integer NOT NULL PRIMARY KEY,
  "somefield" varchar(30) NOT NULL UNIQUE
);

如果您使用postgresql 8.3或更高版本,解决方案非常简单:

ALTER SEQUENCE mike_test_id_seq OWNED BY mike_test.id;

如果你使用的是8.1,那么事情就有点笨拙了。我用以下(最简单的)案例重新创建了我的专栏:

ALTER TABLE mike_test ADD COLUMN temp_id serial NOT NULL;
UPDATE mike_test SET temp_id = id;
ALTER TABLE mike_test DROP COLUMN id;
ALTER TABLE mike_test ADD COLUMN id serial NOT NULL PRIMARY KEY;
UPDATE mike_test SET id = temp_id;
ALTER TABLE mike_test DROP COLUMN temp_id;
SELECT setval('mike_test_id_seq', (SELECT MAX(id) FROM mike_test));

如果您的专栏涉及任何其他限制条件,您将获得更多乐趣。