1

PostgreSQL バージョンを使用9.4.5して、列を含むテーブルがありINETます。その列には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.
4

1 に答える 1

2

そのため、これに関するドキュメントはまだ見つかりませんが、いくつかの実験で理解しました。

制約を作成するときに、列名の後にops クラスを追加する必要があります。

だから(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)
于 2016-01-07T02:32:25.140 に答える