2017-06-19 77 views
1

我對postgres有一個非常非常奇怪的問題。我試圖爲我的數據庫中的業務對象生成GUID,並且我正在爲此使用新的模式。我已經用幾個業務對象完成了這個工作;我在這裏使用的代碼已經過測試並在其他場景下工作。Postgres INSERT INTO ...選擇違反外鍵約束

下面是新表的定義:

CREATE TABLE guid.public_obj 
(
    guid uuid NOT NULL DEFAULT uuid_generate_v4(), 
    id integer NOT NULL, 
    CONSTRAINT obj_guid_pkey PRIMARY KEY (guid), 
    CONSTRAINT obj_id_fkey FOREIGN KEY (id) 
     REFERENCES obj (obj_id) 
     ON UPDATE CASCADE ON DELETE CASCADE 
) 

然而,當我嘗試這個使用下面的代碼回填,我得到一個SQL狀態23503聲稱我違反了外鍵約束。

INSERT INTO guid.public_obj (guid, id) 
SELECT uuid_generate_v4(), o.obj_id 
FROM obj o; 

ERROR: insert or update on table "public_obj" violates foreign key constraint "obj_id_fkey" 
SQL state: 23503 
Detail: Key (id)=(-2) is not present in table "obj". 

但是,如果我做一個SELECT源表,價值肯定是存在:

SELECT uuid_generate_v4(), o.obj_id 
FROM obj o 
WHERE obj_id = -2; 

"0f218286-5b55-4836-8d70-54cfb117d836";-2 

我感到困惑,爲什麼Postgres的可能會認爲我違反了FKEY約束時我直接從相應的表格中提取值。源表定義中obj_id的唯一約束是它是主鍵。它被定義爲一個序列; select將它作爲整數返回。請幫忙!

+1

你是否保持你的模式是直的?我看到你的CREATE TABLE是在'guid'模式中創建的,但'obj'表使用默認模式。 ?? – pbuck

+0

'select relnamespace,relname from pg_class where relname ='obj';' –

+0

我有我的模式直,是的。我使用一個新的模式來保存所有的guid關係,因爲需要guid的業務對象並不都在公共模式中。 – Gideon

回答

0

好的,顯然這是失敗的原因是因爲我不知道表(我強調,它不包含很多元素)是分區的。如果我執行SELECT COUNT(*) FROM obj;它將返回348,但是如果我執行SELECT COUNT(*) FROM ONLY obj;它將返回44.因此,有兩個問題:首先,表中的某些數據尚未正確分區(父表中存在未分區的數據) ,第二,我感興趣的數據跨多個子表分割出來,並且父表上的fkey約束失敗,因爲數據實際上不在父表中。 (注意,這不是我的架構;我不得不使用已經存在很長一段時間的東西。)

分區是通過隱式類型(有三個分區,每個分區都包含相關的行到obj的特定子類型),我認爲最終的解決方案將爲每個子類型創建GUID表。我將不得不處理實際在obj表中的東西,可能是將其選擇到臨時表中,從obj表中刪除行,然後重新插入它們以便它們可以正確分區。