SQLAlchemy:没有文字值渲染器可用于数据类型 REGCONFIG 的文字值“'english'”

pit*_*ddy 3 python postgresql sqlalchemy

我一直在 Docker 容器中运行 Postgres 14/PostGIS 并通过 Flask-SQLAlchemy v3.0.2 与其通信。我在数据库中的一列上设置了全文搜索索引。几个月来我一直没有遇到过任何问题,直到今天我在不更改任何内容的情况下重建了图像。现在,当我尝试创建表时,出现以下错误:

sqlalchemy.exc.CompileError: No literal value renderer is available for literal value "'english'" with datatype REGCONFIG
Run Code Online (Sandbox Code Playgroud)

导致此问题的模型代码:

def create_tsvector(*args):
    field, weight = args[0]
    exp = func.setweight(func.to_tsvector('english', func.coalesce(field, '')), weight)
    for field, weight in args[1:]:
        exp = op(exp, '||', func.setweight(func.to_tsvector('english', func.coalesce(field, '')), weight))
    return exp
Run Code Online (Sandbox Code Playgroud)

这在这里被调用:

class Listing(db.Model):
    __tablename__ = "listing"
    
    ...

    __ts_vector__ = create_tsvector((title, 'A'), (description, 'B'))

    __table_args__ = (
        db.Index(
            'idx_listing_fts',
            __ts_vector__,
            postgresql_using="gin"
        ),
    )
Run Code Online (Sandbox Code Playgroud)

我已经摆脱了文本索引并且服务器启动正常,所以我知道这是导致问题的原因。我还尝试删除“英语”regconfig,但这会导致进一步的问题,并且无论如何我希望 regconfig 位于其中。我可以尝试一种完全不同的构建索引的方法,但我宁愿不这样做,因为它之前工作得很好。

我不知道从哪里开始寻找,因为这似乎是自发发生的,并且根据 Postgres 文档和在线示例,我的模型代码似乎没问题。我对 Docker 仍然不熟悉,PostGIS 图像是否以某种方式发生了变化导致了这个问题?

编辑:我要补充一点,我尝试从 Docker 中重新拉取镜像并从头开始重建容器。仍然遇到同样的问题。

小智 5

全面披露我从来没有真正研究过这里的确切原因,但它显然与升级到 Sqlalchemy 2.x 后 to_tsvector 的第一个参数的输入错误有关。

我通过更新类似的事件解决了这个问题

func.to_tsvector('english', ...)
Run Code Online (Sandbox Code Playgroud)

from sqlalchemy import cast, literal
from sqlalchemy.dialects.postgresql import REGCONFIG
func.to_tsvector(cast(literal("english"), type_=REGCONFIG), ...)
Run Code Online (Sandbox Code Playgroud)

参考

  • to_tsvector 的github问题因 REGCONFIG 的错误键入而中断
  • sqlalchemy 维护者解释python、数据库驱动程序和数据库本身之间的类型转换层