更新:进一步尝试使用psql
简化问题:
对于以下Django模型:
class Book(models.Model):
name = models.TextField(unique=True)
pg_dump
(PostgreSQL 9.3)显示下表&约束:
CREATE TABLE book (
id integer NOT NULL,
name text NOT NULL,
);
ALTER TABLE ONLY book ADD CONSTRAINT book_name_key UNIQUE (name);
CREATE INDEX book_name_like ON book USING btree (name text_pattern_ops);
但是PostgreSQL documentation说:
PostgreSQL 在唯一时自动创建唯一索引 约束[...]是为表定义的。
[...]有 无需在唯一列上手动创建索引;这样做会 只需复制自动创建的索引。
问题:为什么Django会在唯一列上创建索引呢?也许理由是它使用运算符类text_pattern_ops
,因此Django需要添加另一个索引。如果是这种情况,更好的方法是将Django的unique=True
约束解释为:
CREATE UNIQUE INDEX book_name_like ON book USING btree (name text_pattern_ops);
并且根本没有UNIQUE
约束。因此,带UNIQUE INDEX
的单个text_pattern_ops
会导致数据库无法为UNIQUE
约束创建隐式索引。
答案 0 :(得分:15)
问题的核心是Django documentation中的保证:
请注意,当
unique
为True
时,您无需指定db_index
,因为unique
意味着创建索引。
因此,根据Django的合同,unique=True
暗示db_index=True
,而db_index=True
意味着Django必须创建text_pattern_ops
索引以支持所有查找类型(请参阅{{3} })。
至于仅使用一个唯一索引,ticket 12234表示不会涵盖所有查找类型:
请注意,如果您希望涉及普通<,< =,>或> =比较的查询使用索引,则还应使用默认运算符类创建索引。此类查询不能使用xxx_pattern_ops运算符类。
您可以尝试同时添加unique=True
和db_index=False
。
答案 1 :(得分:4)
错误报告中的详细讨论:https://code.djangoproject.com/ticket/24082
分类:在db_index=False
(unique=True
)