我有下表:
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的Employee插入到表中。第一次它顺利导致它是第一个NULL然后在第二次尝试我得到错误:
IntegrityError: duplicate key value violates unique constraint "employee_phonenumber2_key"
DETAIL: Key (phonenumber2)=() already exists.
根据我的理解,NULL不应被视为约束的值,我想要实现的是,不同员工不能复制相同的电话号码或电话号码和电子邮件的组合。
我该如何解决这个问题?
答案 0 :(得分:2)
您根本不是真正插入NULL
,而是插入空字符串''
。如果您插入NULL
,则无法获得您显示的错误。如果您希望使用唯一约束来忽略NULL
,则必须实际使用NULL
。
如果检查PostgreSQL服务器错误日志,您将看到运行的查询;但是,您可能需要打开log_statement = all
以获取所有详细信息。它会显示INSERT
''
phonenumber2
NULL
而不是ALTER TABLE employee ADD CONSTRAINT phonenumber2_nonempty
CHECK (phonenumber2 IS NULL OR length(phonenumber2) > 0);
。
最后证明:
None
它将拒绝任何长度为零的字符串。包括您已经添加的那个您认为为null的那个,因此添加检查约束将失败。
你似乎在使用Django,提到你的“models.py”。 Django的IMO很不认为Python值''
应该存储在字符字段中NULL
,而不是''
;它将None
和''
都视为“空值”。 You can tell it to store None as NULL
with Field.null
。我不确定它是否会强制NULL
存储为{{1}};我希望不是,但没有经过测试。