我正在尝试使用 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 答案,我的代码/语法看起来不错。
我的代码基于:
“||”在调用 op.create_index 时引起了问题,所以我最终切换到 op.execute 而不是使用原始 SQL 文本。
我还必须将
literal_column(f'"{ts_config}"'), field)
替换为 func.to_tsvector(bindparam("ts_config", ts_config, type_=Text)
以避免我的问题的第二个链接中提到的编译错误,以及在此 Github 问题评论线程中提到的编程错误。