SQLAlchemy + Alembic:如何使用 Alembic 修订版为具有权重的列创建全文搜索索引

问题描述 投票:0回答:1

我正在尝试使用 Alembic 生成一个修订版,该修订版将为我的表中的某些列创建全文搜索索引。我最近升级到 SQLAlchemy 2.0 和 PG15。每当我尝试运行

alembic upgrade head
时,我都会收到语法错误。

我使用的 Alembic 代码是:

op.create_index('idx_obj_eng_ts_vector', 'Objects', [sa.text('(setweight(to_tsvector("english", col_name_1), \'A\') || setweight(to_tsvector("english", col_name_2), \'B\')) || setweight(to_tsvector("english", col_name_3), \'C\')')], unique=False, postgresql_using='gin')

我用来生成的模型代码是:

def create_tsvector(
    field_with_weights: list[tuple[str, str]], ts_config: str = "english"
):
    field, weight = field_with_weights[0]
    exp = func.setweight(
        func.to_tsvector(literal_column(f'"{ts_config}"'), field), weight
    )

    for field, weight in field_with_weights[1:]:
        exp = op(
            exp,
            "||",
            func.setweight(
                func.to_tsvector(literal_column(f'"{ts_config}"'), field), weight
            ),
        )

    return exp

这被称为:

class Objects(Base):
    __tablename__ = "Objects"
    
    col_name_1 = Column(String)
    col_name_2 = Column(String)
    col_name_3 = Column(String)

    ...

    __object_eng_ts_vector__ = create_tsvector(
        field_with_weights=[(col_name_1, "A"), (col_name_2, "B"), (col_name_3, "C")],
        ts_config="english",
    )

    __table_args__ = (
        Index("idx_object_eng_ts_vector", __object_eng_ts_vector__, postgresql_using="gin"),
    )

我拨打

alembic upgrade head
时收到的错误是:

psycopg2.errors.SyntaxError: syntax error at or near "||"
Sep 26 02:11:28 AM  LINE 1: ...| setweight(to_tsvector("english", col_name_2), 'B')) || setweig...
Sep 26 02:11:28 AM                                                               ^
Sep 26 02:11:28 AM  
Sep 26 02:11:28 AM  
Sep 26 02:11:28 AM  The above exception was the direct cause of the following exception:
...
sqlalchemy.exc.ProgrammingError: (psycopg2.errors.SyntaxError) syntax error at or near "||"
Sep 26 02:11:28 AM  LINE 1: ...| setweight(to_tsvector("english", col_name_2), 'B')) || setweig...
Sep 26 02:11:28 AM                                                               ^
Sep 26 02:11:28 AM  
Sep 26 02:11:28 AM  [SQL: CREATE INDEX idx_object_eng_ts_vector ON "Objects" USING gin ((setweight(to_tsvector("english", col_name_1), 'A') || setweight(to_tsvector("english", col_name_2), 'B')) || setweight(to_tsvector("english", col_name_3), 'C'))]
Sep 26 02:11:28 AM  (Background on this error at: https://sqlalche.me/e/20/f405)

但是根据文档/其他 StackOverflow 答案,我的代码/语法看起来不错。

我的代码基于:

  1. 在 PostgreSQL 上使用 SQLAlchemy 创建全文搜索索引
  2. SQLAlchemy:没有文字值渲染器可用于数据类型 REGCONFIG 的文字值“'english'”
python postgresql sqlalchemy full-text-search alembic
1个回答
0
投票

“||”在调用 op.create_index 时引起了问题,所以我最终切换到 op.execute 而不是使用原始 SQL 文本。

我还必须将

literal_column(f'"{ts_config}"'), field)
替换为
func.to_tsvector(bindparam("ts_config", ts_config, type_=Text)
以避免我的问题的第二个链接中提到的编译错误,以及在此 Github 问题评论线程中提到的编程错误。

© www.soinside.com 2019 - 2024. All rights reserved.