【问题标题】:Postgres error: null value in column "id" - during insert operationPostgres 错误:“id”列中的空值 - 在插入操作期间
【发布时间】:2016-12-12 16:32:10
【问题描述】:

我使用 postgresql 和 yii2 框架。 好吧,我收到了一条非常有趣的错误消息:

SQLSTATE[23502]: Not null violation: 7 ERROR: null value in column "id" violates not-null constraint
DETAIL: Failing row contains (null, 1, null, null, null, null, 1, Demo, , , , 1998-01-01, , , , 345345435453453, , , , , 1, , , f, f, f, f, 10, f, 1, f, f, f, null, null, null, 1470477479, 1470477479, null).

但是我检查了我的插入命令,那里没有“id”列!

INSERT INTO "advertiser" ("languages", "type", "name", "display_name", "title", "about", "birthday", "gender", "country_id", "county_id", "city_id", "city_part", "street", "house_number", "phone", "public_email", "public_url", "motto", "message", "im_facebook", "im_skype", "has_viber", "has_whatsapp", "has_sms_response", "visible_birthday", "is_checked", "status", "version", "user_id", "created_at", "updated_at") VALUES (NULL, 1, 'Demo', '', '', '', '1998-01-01', 1, NULL, NULL, NULL, '', '', '', '345345435453453', '', '', '', '', '', '', FALSE, FALSE, FALSE, FALSE, FALSE, 10, NULL, 1, 1470477479, 1470477479) RETURNING "id"

所以我真的无法理解这个错误信息。我没有发现 Postgres 或 Yii 尝试插入空 ID 值或什么。

顺便说一下,你可以在这里找到结构

                                                    Table "public.advertiser"
        Column         |          Type          |            Modifiers            | Storage  | Stats target | Description 
-----------------------+------------------------+---------------------------------+----------+--------------+-------------
 id                    | integer                | not null                        | plain    |              | 
 user_id               | integer                |                                 | plain    |              | 
 country_id            | integer                |                                 | plain    |              | 
 county_id             | integer                |                                 | plain    |              | 
 city_id               | integer                |                                 | plain    |              | 
 district_id           | integer                |                                 | plain    |              | 
 type                  | smallint               |                                 | plain    |              | 
 name                  | character varying(255) | not null                        | extended |              | 
 display_name          | character varying(255) | default NULL::character varying | extended |              | 
 title                 | character varying(255) | default NULL::character varying | extended |              | 
 about                 | text                   |                                 | extended |              | 
 birthday              | date                   | not null                        | plain    |              | 
 city_part             | character varying(255) | default NULL::character varying | extended |              | 
 street                | character varying(255) | default NULL::character varying | extended |              | 
 house_number          | character varying(20)  | default NULL::character varying | extended |              | 
 phone                 | character varying(15)  | not null                        | extended |              | 
 public_email          | character varying(255) | default NULL::character varying | extended |              | 
 public_url            | character varying(255) | default NULL::character varying | extended |              | 
 motto                 | character varying(255) | default NULL::character varying | extended |              | 
 message               | text                   |                                 | extended |              | 
 gender                | smallint               | not null default 1              | plain    |              | 
 im_facebook           | character varying(255) | default NULL::character varying | extended |              | 
 im_skype              | character varying(255) | default NULL::character varying | extended |              | 
 has_viber             | boolean                | not null default false          | plain    |              | 
 has_whatsapp          | boolean                | not null default false          | plain    |              | 
 has_sms_response      | boolean                | not null default false          | plain    |              | 
 visible_birthday      | boolean                | not null default false          | plain    |              | 
 status                | smallint               | not null default 10             | plain    |              | 
 is_checked            | boolean                | not null default false          | plain    |              | 
 geo_latitude          | double precision       |                                 | plain    |              | 
 geo_longitude         | double precision       |                                 | plain    |              | 
 languages             | integer[]              |                                 | extended |              | 
 created_at            | integer                |                                 | plain    |              | 
 updated_at            | integer                |                                 | plain    |              | 
 version               | bigint                 | default 0                       | plain    |              | 
Indexes:
    "advertiser_pkey" PRIMARY KEY, btree (id)

你有什么建议?我应该在哪里寻找问题?

【问题讨论】:

    标签: sql postgresql yii null sql-insert


    【解决方案1】:

    如果由于某种原因,您无法更改架构以将 id 列的类型从现在的任何类型更改为 serialize;然后,您可以像这样插入 id 以及其他值:

    (select max(id) + 1 from table)

    【讨论】:

    • 相信您的意思是 SERIAL,而不是 serialize
    【解决方案2】:

    在将 PostgreSQL10 转储读入 9.6 数据库服务器后发生在我身上。之后,要自动创建顺序 ID 的序列丢失了。

    这可以这样显示(在 psql 中):

    SELECT  column_name
    ,       column_default
    FROM    information_schema.columns
    WHERE   table_name = 'django_migrations'
    ORDER BY 
        ordinal_position;
    

    其中django_migrations 是表名。它应该显示如下内容:

     column_name |                column_default                 
    -------------+-----------------------------------------------
     id          | nextval('django_migrations_id_seq'::regclass)
    [...]
    

    如果 'column_default' 中的值为空,则序列丢失。

    【讨论】:

    • 你是如何解决这个问题的?
    • 我使用的是 Mac,并且有 Postgresql.app (www.postgresqlapp.com) 允许并行安装多个版本,因此我可以即时切换数据库服务器版本。 Linux(甚至可能是 Windows)也应该有解决方案
    【解决方案3】:

    如果您因为客户端、管理、数据库权限等原因无法更改为serial...

    数据库可能正在使用sequence

    以下是关于它的信息:SELECT nextval('seq_nuu_filtreelement')

    阅读:

    我没有设法让pg_catalog.pg_get_serial_sequence('schema.table', 'id') 工作。

    因此我在数据库浏览器中找到了序列并使用命令:

    SELECT nextval('seq_table_name')

    【讨论】:

      【解决方案4】:

      serial 关键字在解析时展开,之后就看不到了。

      Postgresql 10 版本开始,有以下替代方案:

      id int GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY
      

      它应该符合SQL标准,因此与Oracle兼容。

      查看blog了解更多详情。

      【讨论】:

      • “默认”和“总是”有什么区别?
      【解决方案5】:

      将您现有的主键更改为 serial 。阅读此内容以进行更改

      Changing primary key int type to serial

      【讨论】:

        【解决方案6】:

        您没有为id 插入值。由于您没有显式设置它,因此它被隐式地赋予了一个 null 值,这当然不是主键列的有效值。您可以通过将此列定义为 serial 而不是普通的旧 integer 来避免这整个情况,并将所有繁重的工作留给数据库。

        【讨论】:

          猜你喜欢
          • 2021-06-26
          • 2014-05-05
          • 2021-12-24
          • 2010-10-03
          • 1970-01-01
          • 1970-01-01
          • 2017-03-18
          • 1970-01-01
          • 2022-10-09
          相关资源
          最近更新 更多