PostgreSQL UPSERT (INSERT ... ON CONFLICT UPDATE) 失败
PostgreSQL UPSERT (INSERT ... ON CONFLICT UPDATE) fails
我的 postgresql 数据库中有一行要更新。
=> SELECT * FROM reading_group_reading_session
WHERE group_id = 439
AND group_type = 'focus_group'
AND reg_user_id = 28056
AND device_id = ''
AND reading_date = '2021-06-03';
id | group_id | group_type | reg_user_id | device_id | reading_date | seconds_reading | num_syncs
-------+----------+-------------+-------------+-----------+--------------+-----------------+-----------
35532 | 439 | focus_group | 28056 | | 2021-06-03 | 3310 | 4
(1 row)
Time: 1.820 ms
=>
我的代码生成此 SQL 语句以插入其他更新已更改的字段:
=> INSERT INTO
[more] - > INSERT INTO reading_group_reading_session
(group_id,group_type,reg_user_id,device_id,reading_date,seconds_reading)
VALUES
(439,'focus_group',28056,'','2021-06-03',3320)
ON CONFLICT
(group_id, group_type, reg_user_id, device_id, reading_date)
DO UPDATE SET
seconds_reading = 3320;
ERROR: 23502: null value in column "num_syncs" violates not-null constraint
DETAIL: Failing row contains (115399, 439, focus_group, 28056, , 2021-06-03, 3320, null).
SCHEMA NAME: public
TABLE NAME: reading_group_reading_session
COLUMN NAME: num_syncs
LOCATION: ExecConstraints, execMain.c:1700
Time: 3.017 ms
=>
我不明白的是,我可以 select 那一行,并且它与非 NULL num_syncs 一起出现。但是 UPSERT 失败了,因为它没有(重新)设置 num_syncs(值 4 不变)。
有人看到我遗漏了什么吗?
Fwiw,table 定义是这样的:
Table "public.reading_group_reading_session"
Column | Type | Modifiers
-----------------+-----------------+----------------------------------------------------------------------------
id | integer | not null default nextval('reading_group_reading_session_id_seq'::regclass)
group_id | integer | not null
group_type | group_type_name |
reg_user_id | integer | not null
device_id | text |
reading_date | date |
seconds_reading | integer | not null
num_syncs | integer | not null
Indexes:
"reading_group_reading_session_pkey" PRIMARY KEY, btree (id)
"reading_group_reading_session_idx_dgid" UNIQUE, btree (group_id, group_type, reg_user_id, device_id, reading_date)
Check constraints:
"reading_group_reading_session_group_id_check" CHECK (group_id > 0)
"reading_group_reading_session_minutes_reading_check" CHECK (seconds_reading >= 0)
"reading_group_reading_session_num_syncs_check" CHECK (num_syncs >= 0)
"reading_group_reading_session_reg_user_id_check" CHECK (reg_user_id >= 0)
=>
首先检查 NOT NULL
约束。这是有道理的,因为必须满足它们才能使 INSERT
成功。
如果您确定已经有匹配的行,请使用常规 UPDATE
。
替代方法可能是使用 CHECK (colname IS NOT NULL)
约束而不是 NOT NULL
。
我的 postgresql 数据库中有一行要更新。
=> SELECT * FROM reading_group_reading_session
WHERE group_id = 439
AND group_type = 'focus_group'
AND reg_user_id = 28056
AND device_id = ''
AND reading_date = '2021-06-03';
id | group_id | group_type | reg_user_id | device_id | reading_date | seconds_reading | num_syncs
-------+----------+-------------+-------------+-----------+--------------+-----------------+-----------
35532 | 439 | focus_group | 28056 | | 2021-06-03 | 3310 | 4
(1 row)
Time: 1.820 ms
=>
我的代码生成此 SQL 语句以插入其他更新已更改的字段:
=> INSERT INTO
[more] - > INSERT INTO reading_group_reading_session
(group_id,group_type,reg_user_id,device_id,reading_date,seconds_reading)
VALUES
(439,'focus_group',28056,'','2021-06-03',3320)
ON CONFLICT
(group_id, group_type, reg_user_id, device_id, reading_date)
DO UPDATE SET
seconds_reading = 3320;
ERROR: 23502: null value in column "num_syncs" violates not-null constraint
DETAIL: Failing row contains (115399, 439, focus_group, 28056, , 2021-06-03, 3320, null).
SCHEMA NAME: public
TABLE NAME: reading_group_reading_session
COLUMN NAME: num_syncs
LOCATION: ExecConstraints, execMain.c:1700
Time: 3.017 ms
=>
我不明白的是,我可以 select 那一行,并且它与非 NULL num_syncs 一起出现。但是 UPSERT 失败了,因为它没有(重新)设置 num_syncs(值 4 不变)。
有人看到我遗漏了什么吗?
Fwiw,table 定义是这样的:
Table "public.reading_group_reading_session"
Column | Type | Modifiers
-----------------+-----------------+----------------------------------------------------------------------------
id | integer | not null default nextval('reading_group_reading_session_id_seq'::regclass)
group_id | integer | not null
group_type | group_type_name |
reg_user_id | integer | not null
device_id | text |
reading_date | date |
seconds_reading | integer | not null
num_syncs | integer | not null
Indexes:
"reading_group_reading_session_pkey" PRIMARY KEY, btree (id)
"reading_group_reading_session_idx_dgid" UNIQUE, btree (group_id, group_type, reg_user_id, device_id, reading_date)
Check constraints:
"reading_group_reading_session_group_id_check" CHECK (group_id > 0)
"reading_group_reading_session_minutes_reading_check" CHECK (seconds_reading >= 0)
"reading_group_reading_session_num_syncs_check" CHECK (num_syncs >= 0)
"reading_group_reading_session_reg_user_id_check" CHECK (reg_user_id >= 0)
=>
首先检查 NOT NULL
约束。这是有道理的,因为必须满足它们才能使 INSERT
成功。
如果您确定已经有匹配的行,请使用常规 UPDATE
。
替代方法可能是使用 CHECK (colname IS NOT NULL)
约束而不是 NOT NULL
。