ERROR: data type inet has no default operator class for access method "gist"
ERROR: data type inet has no default operator class for access method "gist"
使用 PostgreSQL 版本 9.4.5
,我有一个包含 INET
列的 table。
在该专栏中,我有一个 gist
索引
CREATE TABLE ipv4_prefix (
id uuid DEFAULT public.uuid_generate_v4() NOT NULL,
prefix inet NOT NULL,
CONSTRAINT ck_ipv4_prefix_valid_ipv4 CHECK ((family(prefix) = 4))
);
ALTER TABLE ONLY ipv4_prefix ADD CONSTRAINT pk_ipv4_prefix PRIMARY KEY (id);
CREATE INDEX ipv4_prefix_gist_index ON ipv4_prefix USING gist (prefix inet_ops);
这一切似乎都有效:
mimir=# \d ipv4_prefix
Table "ipv4_prefix"
Column | Type | Modifiers
--------+------+-------------------------------------
id | uuid | not null default uuid_generate_v4()
prefix | inet | not null
Indexes:
"pk_ipv4_prefix" PRIMARY KEY, btree (id)
"ipv4_prefix_gist_index" gist (prefix inet_ops)
Check constraints:
"ck_ipv4_prefix_valid_ipv4" CHECK (family(prefix) = 4)
但是,当我尝试添加 EXCLUDE
约束时:
ALTER TABLE ipv6_prefix ADD CONSTRAINT ipv6_prefix_exclude_constraint EXCLUDE USING gist (prefix WITH &&);
我收到以下错误:
ERROR: data type inet has no default operator class for access method "gist"
HINT: You must specify an operator class for the index or define a default operator class for the data type.
所以,我仍然没有找到这方面的文档,但通过一些实验弄明白了。
创建约束时需要在列名后添加ops class。
所以 (prefix inet_ops WITH &&)
而不是 (prefix WITH &&)
对于那些使用 SQLAlchemy 的人,您可以通过以下方式偷偷摸摸:
class IPv4PrefixTable(IPPrefixTable):
__tablename__ = 'ipv4_prefix'
__table_args__ = (
Index('ipv4_prefix_gist_index', 'prefix', postgresql_using='gist', postgresql_ops={
'prefix': 'inet_ops'
}),
ExcludeConstraint(('prefix inet_ops', '&&'), using='gist', name='ipv4_prefix_exclude_constraint'),
{'schema': 'mimir'}
)
id = Column(UUID(as_uuid=True), primary_key=True, server_default=func.uuid_generate_v4())
prefix = Column(INET, CheckConstraint('family(prefix) = 4', name='valid_ipv4'), unique=False, nullable=False)
使用 PostgreSQL 版本 9.4.5
,我有一个包含 INET
列的 table。
在该专栏中,我有一个 gist
索引
CREATE TABLE ipv4_prefix (
id uuid DEFAULT public.uuid_generate_v4() NOT NULL,
prefix inet NOT NULL,
CONSTRAINT ck_ipv4_prefix_valid_ipv4 CHECK ((family(prefix) = 4))
);
ALTER TABLE ONLY ipv4_prefix ADD CONSTRAINT pk_ipv4_prefix PRIMARY KEY (id);
CREATE INDEX ipv4_prefix_gist_index ON ipv4_prefix USING gist (prefix inet_ops);
这一切似乎都有效:
mimir=# \d ipv4_prefix
Table "ipv4_prefix"
Column | Type | Modifiers
--------+------+-------------------------------------
id | uuid | not null default uuid_generate_v4()
prefix | inet | not null
Indexes:
"pk_ipv4_prefix" PRIMARY KEY, btree (id)
"ipv4_prefix_gist_index" gist (prefix inet_ops)
Check constraints:
"ck_ipv4_prefix_valid_ipv4" CHECK (family(prefix) = 4)
但是,当我尝试添加 EXCLUDE
约束时:
ALTER TABLE ipv6_prefix ADD CONSTRAINT ipv6_prefix_exclude_constraint EXCLUDE USING gist (prefix WITH &&);
我收到以下错误:
ERROR: data type inet has no default operator class for access method "gist"
HINT: You must specify an operator class for the index or define a default operator class for the data type.
所以,我仍然没有找到这方面的文档,但通过一些实验弄明白了。
创建约束时需要在列名后添加ops class。
所以 (prefix inet_ops WITH &&)
而不是 (prefix WITH &&)
对于那些使用 SQLAlchemy 的人,您可以通过以下方式偷偷摸摸:
class IPv4PrefixTable(IPPrefixTable):
__tablename__ = 'ipv4_prefix'
__table_args__ = (
Index('ipv4_prefix_gist_index', 'prefix', postgresql_using='gist', postgresql_ops={
'prefix': 'inet_ops'
}),
ExcludeConstraint(('prefix inet_ops', '&&'), using='gist', name='ipv4_prefix_exclude_constraint'),
{'schema': 'mimir'}
)
id = Column(UUID(as_uuid=True), primary_key=True, server_default=func.uuid_generate_v4())
prefix = Column(INET, CheckConstraint('family(prefix) = 4', name='valid_ipv4'), unique=False, nullable=False)