2014-01-31 114 views
1

我有以下表格:Postrgersql + Django的:NULL值會導致IntegrityError:重複鍵值違反唯一約束

Column  |   Type    |       Modifiers       
----------------+-----------------------------+--------------------------------------------------------------- 
user_id   | bigint      | not null default nextval('employee_user_id_seq'::regclass) 
name   | character varying(50)  | not null              
phonenumber  | character varying(20)  | not null              
phonenumber2 | character varying(20)  |                
email   | character varying(75)  |  
Indexes: 
"employee_pkey" PRIMARY KEY, btree (user_id) 
"employee_email_key" UNIQUE CONSTRAINT, btree (email) 
"employee_phonenumber2_key" UNIQUE CONSTRAINT, btree (phonenumber2) 
"employee_phonenumber_email_key" UNIQUE CONSTRAINT, btree (phonenumber, email) 
"employee_phonenumber_key" UNIQUE CONSTRAINT, btree (phonenumber)               

在models.py:

class Employee(models.Model): 
    user_id = models.AutoField(primary_key=True) 
    name = models.CharField(max_length=50) 
    phonenumber = models.CharField(max_length=20, unique=True) 
    phonenumber2 = models.CharField(max_length=20, unique=True) 
    email = models.EmailField(blank=True, unique=True) 

使用Django我已經插入了沒有phonenumber2的員工進入表格。它會順利的事業,這是第NULL,則在第二次嘗試第一次我得到的錯誤:

IntegrityError: duplicate key value violates unique constraint "employee_phonenumber2_key" 
DETAIL: Key (phonenumber2)=() already exists. 

從我的理解NULL不應被視爲限制值,我想要實現的是同一電話號碼或電話號碼與電子郵件的組合不能爲不同的員工複製。

我該如何解決這個問題?

+0

「models.py」。瘋狂猜測,你使用的是Django? (這是一件很好的事,或者至少是標籤)。 –

+0

@CraigRinger謝謝,我已經編輯了這個問題 –

回答

2

根本不是真的插入NULL,而是插入空字符串''。如果您插入了NULL,則無法獲取您顯示的錯誤。如果你想要一個唯一的約束來忽略NULL,你必須實際使用NULL

如果您檢查PostgreSQL服務器錯誤日誌,您將看到運行的查詢;不過,您可能需要啓用log_statement = all以獲取所有詳細信息。它將顯示爲''phonenumber2,而不是NULL

要決定性地證明這一點:

ALTER TABLE employee ADD CONSTRAINT phonenumber2_nonempty 
CHECK (phonenumber2 IS NULL OR length(phonenumber2) > 0); 

它會拒絕具有零個長度字符串的所有行。包括你已經添加的那個你認爲是空的,所以添加檢查約束將會失敗。

您似乎在使用Django,通過提及「models.py」。 Django有IMO糟糕的觀點,認爲Python值None應該存儲在字符字段中,如'',而不是NULL;它將''None都視爲「空值」。 You can tell it to store None as NULL with Field.null。我不確定它是否會強制''存儲爲NULL;我希望沒有,但沒有經過測試。

+0

@liva建議一個新的問題,如果你在調查了一下後無法弄清楚它。我不使用Django。 –

相關問題