2017-02-03 2 views
8
삽입 할 경우 다음과 같은 종류의 일을 할 때 나는 다음과 같은 오류를 받고 있어요

과 일치하는 고유하거나 배제 제한하지 :를 ON CONFLICT

검색어 :

INSERT INTO accounts (type, person_id) VALUES ('PersonAccount', 1) ON 
CONFLICT (type, person_id) WHERE type = 'PersonAccount' DO UPDATE SET 
updated_at = EXCLUDED.updated_at RETURNING * 

오류 :

SQL execution failed (Reason: ERROR: there is no unique or exclusion constraint matching the ON CONFLICT specification)

I을 고유 한 INDEX도 있습니다.

CREATE UNIQUE INDEX uniq_person_accounts ON accounts USING btree (type, 
person_id) WHERE ((type)::text = 'PersonAccount'::text); 

가끔은 작동하지만 때때로 그렇지는 않습니다. I 무작위로 예외가 발생합니다. 이는 정말 이상합니다. INDEX에 액세스 할 수 없거나 존재하지 않는다고 생각됩니다.

의견이 있으십니까?

저는 PostgreSQL 9.5.5를 사용하고 있습니다. 찾기 또는 계정을 만들려고 코드를 실행하는 동안

예 :이 경우

INSERT INTO accounts (type, person_id, created_at, updated_at) VALUES ('PersonAccount', 69559, '2017-02-03 12:09:27.259', '2017-02-03 12:09:27.259') ON CONFLICT (type, person_id) WHERE type = 'PersonAccount' DO UPDATE SET updated_at = EXCLUDED.updated_at RETURNING * 
SQL execution failed (Reason: ERROR: there is no unique or exclusion constraint matching the ON CONFLICT specification) 

을, 나는 계정이 존재하지 않음을 확신합니다. 또한 사용자가 이미 계정을 가지고있을 때 오류를 출력하지 않습니다. 문제는 계정이없는 경우에도 작동하는 경우도 있습니다. 쿼리는 정확히 동일합니다.

+1

를 어쩌면이 부분 인덱스입니다 .. –

+0

당신은 정교한 때문에? –

+0

@VaoTsun 부분 색인은'ON CONFLICT'에 의해 지원됩니다. – pozs

답변

1

나는 UPSERT 함께 플레이 할 수있는 기회가 없었어요,하지만 난 당신이 docs의 경우 생각 :

Note that this means a non-partial unique index (a unique index without a predicate) will be inferred (and thus used by ON CONFLICT) if such an index satisfying every other criteria is available. If an attempt at inference is unsuccessful, an error is raised.

+1

필자는 문서에서도 그러한 것을 보았습니다.하지만 내 해석에 따르면 인덱스를 추론 할 수 없다면 때로는 가끔씩 그렇게하지 않아야합니다. 게다가, 이것은 생성되지 않은 부분적인 고유 인덱스에 대한 동작을 지정합니다. 필자의 경우, 부분 고유 인덱스를 사용하고 있습니다. –