【问题标题】:Django AutoField not returning new primary_keyDjango AutoField 不返回新的 primary_key
【发布时间】:2011-07-21 16:23:02
【问题描述】:

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

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

它给了我们这个,我们添加了 primary_key 和 unique 等于 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

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

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

【问题讨论】:

    标签: django postgresql


    【解决方案1】:

    我刚刚遇到了同样的事情,但是在一个历史悠久的项目的 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));
    

    如果您的专栏涉及任何其他约束,您将获得更多乐趣。

    【讨论】:

      猜你喜欢
      • 2016-10-09
      • 1970-01-01
      • 1970-01-01
      • 2016-02-01
      • 2018-03-05
      • 1970-01-01
      • 1970-01-01
      • 2015-02-17
      • 2018-12-12
      相关资源
      最近更新 更多