我正在尝试使用SQLAlchemy-searchable在模型列上启用全文搜索。我按照quickstart guide上的说明操作,并应用this github issue中指定的修复程序,因为我正在使用Flask。此外,我已经创建并应用了Alembic Migrations docs部分中指定的迁移。但是,引发了以下异常:
sqlalchemy.exc.ProgrammingError: (psycopg2.ProgrammingError) function
tsq_parse(unknown, unknown) does not exist
LINE 3: WHERE quote.qt_search_vector @@ tsq_parse('pg_catalog.englis...
^
HINT: No function matches the given name and argument types. You might need
to add explicit type casts. [SQL: 'SELECT quote.id AS quote_id, quote.song_id AS
quote_song_id, quote.stanza_id AS quote_stanza_id, quote.popularity_count AS
quote_popularity_count, quote.quote_text AS quote_quote_text,
quote.qt_search_vector AS quote_qt_search_vector \nFROM quote \nWHERE
quote.qt_search_vector @@ tsq_parse(%(tsq_parse_1)s, %(tsq_parse_2)s) \n
LIMIT %(param_1)s'] [parameters: {'tsq_parse_1': 'pg_catalog.english',
'tsq_parse_2': '"ipsum"', 'param_1': 10}]
(Background on this error at: http://sqlalche.me/e/f405)
我错过了什么吗?
__初始化__。PY
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy_searchable import make_searchable
Base = declarative_base()
make_searchable(Base.metadata)
... more code ...
模型
class QuoteQuery(BaseQuery, SearchQueryMixin):
pass
class Quote(db.Model):
query_class = QuoteQuery
__table_args__ = (
db.UniqueConstraint('song_id', 'stanza_id', 'quote_text'),)
id = db.Column(db.Integer, primary_key=True)
song_id = db.Column(
db.Integer, db.ForeignKey('song.id'), nullable=False)
stanza_id = db.Column(
db.Integer, db.ForeignKey('stanza.id'), nullable=True)
popularity_count = db.Column(
db.BigInteger, unique=False, nullable=False, server_default='1')
quote_text = db.Column(db.Text, unique=False, nullable=False)
qt_search_vector = db.Column(TSVectorType('quote_text'))
查询
term = 'lorem'
Quote.query.search('"' + term + '"').all()
答案 0 :(得分:0)
这是我提供make_searchable函数的元数据的问题。修复了make_searchable调用:
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy_searchable import make_searchable
db = SQLAlchemy()
make_searchable(db.metadata)
在此之后,我调用了db.create_all(),全文搜索开始按预期工作。
答案 1 :(得分:0)
对于那些不使用 Flask 的人,这是我的解决方案:
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import configure_mappers
db_engine = create_engine(...)
configure_mappers()
Base = declarative_base()
make_searchable(Base.metadata)
Base.metadata.create_all(db_engine)
缺失的部分是 Base.metadata.create_all(db_engine)
答案 2 :(得分:0)
我在这里解决了一天的问题。也许这会帮助别人。我有时也缺少函数 parse_websearch
而不是 tsq_parse
,但在我修复它之前我无法缩小为什么它会给出一个或另一个。
我的问题是我升级了 sqlalchemy_searchable(从 0.10.2 到 1.4),而我的数据库版本(Postgres 9.6)现在太旧了。我现在需要从 sqlalchemy_searchable 手动创建一些函数,但我缺少 Postgres 函数(特别是在 11 中添加的 websearch_to_tsquery
)。
我使用 Flask-Migrate/Alembic 进行迁移。我得到了 here 的帮助,最终进行了一次空白迁移(flask db revision
来做到这一点)。我粘贴了来自 here 的 SQL。我的新迁移看起来像这样。
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = 'AAA'
down_revision = 'BBB'
branch_labels = None
depends_on = None
def upgrade():
command = """
CREATE OR REPLACE FUNCTION parse_websearch(config regconfig, search_query text)
RETURNS tsquery AS $$
SELECT
string_agg(
(
CASE
WHEN position('''' IN words.word) > 0 THEN CONCAT(words.word, ':*')
ELSE words.word
END
),
' '
)::tsquery
FROM (
SELECT trim(
regexp_split_to_table(
websearch_to_tsquery(config, lower(search_query))::text,
' '
)
) AS word
) AS words
$$ LANGUAGE SQL IMMUTABLE;
CREATE OR REPLACE FUNCTION parse_websearch(search_query text)
RETURNS tsquery AS $$
SELECT parse_websearch('pg_catalog.simple', search_query);
$$ LANGUAGE SQL IMMUTABLE;"""
op.execute(command)
def downgrade():
op.execute('DROP FUNCTION public.parse_websearch(regconfig, text);')
op.execute('DROP FUNCTION public.parse_websearch(text);')