我在 Postgres 表上手动创建了 GIN 索引,如下所示:
create index idx_ib_keywords on stuff using gin(to_tsvector('english'::regconfig, keywords));
它创建得很好:
\d info_block_template
Table info_block_template
Column | Type | Collation | Nullable | Default
------------+--------+-----------+----------+--------
.
.
.
keywords | text | | not null |
.
.
.
Indexes:
.
. "idx_ib_keywords" gin (to_tsvector('english'::regconfig, keywords))
现在,我正在使用 alembic 进行迁移。当我使用 alembic 自动生成迁移时,GIN 索引不会自动生成。不用担心,自动生成器并不应该是完美的。所以我想进去手工编辑迁移文件。
我已经搜索了如何做到这一点,我能找到的最接近的东西是我关注并写下的此页面
op.create_index(op.f('idx_ib_keywords'), 'stuff', ['keywords'], postgresql_using='gin')
进入我的迁移脚本。当我应用此迁移时,我收到错误:
sqlalchemy.exc.ProgrammingError:(psycopg2.errors.UndefinedObject)数据类型文本没有访问方法“gin”的默认运算符类 提示:您必须为索引指定一个运算符类或为数据类型定义一个默认运算符类。这是一个很棒的错误消息;它告诉我我需要做
to_tsvector
的事情。但是,我不知道如何在 SQLAlchemy 中做到这一点。有没有一种简单的方法可以在 SQLAlchemy 中编写此内容,或者我应该在迁移文件中使用原始 SQL?
不是作为postgresql_using
kwarg 的一部分。正确的 SQLAlchemy 语句是:
op.create_index(op.f('idx_ib_keywords'),
'info_block_template',
[sa.text('to_tsvector(\'english\'::regconfig, keywords)')],
postgresql_using='gin')
应用此迁移时,新创建的索引将完全按照预期显示:
"idx_ib_keywords" gin (to_tsvector('english'::regconfig, keywords))
它也适用于索引的 btree 查询。例如
op.create_index(op.f('ix_index_name'), 'table_name',
[sa.text('(jsonb_column_name #>> \'{top_level_object,second_level}\')')])
import sqlalchemy as sa
metadata = sa.MetaData()
sa.Table(
"table_name",
metadata,
# ... list of columns and other indexes ...
sa.Index(
"ix_index_name",
sa.sql.expression.text("to_tsvector('english'::regconfig, keywords)"),
postgresql_using="gin",
)
)