Fix: pg_trgm optional, table creation no longer fails without it
Some checks failed
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / test-go-school (push) Successful in 1m9s
CI / test-go-edu-search (push) Successful in 1m4s
CI / test-python-klausur (push) Failing after 2m59s
CI / test-python-agent-core (push) Successful in 33s
CI / test-nodejs-website (push) Successful in 28s
Some checks failed
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / test-go-school (push) Successful in 1m9s
CI / test-go-edu-search (push) Successful in 1m4s
CI / test-python-klausur (push) Failing after 2m59s
CI / test-python-agent-core (push) Successful in 33s
CI / test-nodejs-website (push) Successful in 28s
Trigram extension and index are now created in a separate try/catch so table creation succeeds even without pg_trgm. Search falls back to ILIKE when trigram functions are not available. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -75,14 +75,16 @@ async def init_vocabulary_tables():
|
||||
ON vocabulary_words (difficulty);
|
||||
CREATE INDEX IF NOT EXISTS idx_vocab_tags
|
||||
ON vocabulary_words USING GIN (tags);
|
||||
CREATE INDEX IF NOT EXISTS idx_vocab_english_trgm
|
||||
ON vocabulary_words USING GIN (english gin_trgm_ops);
|
||||
""")
|
||||
# Enable trigram extension for fuzzy search (may already exist)
|
||||
# Enable trigram extension for fuzzy search (optional)
|
||||
try:
|
||||
await conn.execute("CREATE EXTENSION IF NOT EXISTS pg_trgm;")
|
||||
await conn.execute("""
|
||||
CREATE INDEX IF NOT EXISTS idx_vocab_english_trgm
|
||||
ON vocabulary_words USING GIN (english gin_trgm_ops);
|
||||
""")
|
||||
except Exception:
|
||||
logger.info("pg_trgm extension already exists or cannot be created")
|
||||
logger.info("pg_trgm not available — trigram search disabled, using LIKE fallback")
|
||||
|
||||
logger.info("vocabulary_words table initialized")
|
||||
|
||||
@@ -140,19 +142,31 @@ def _row_to_word(row) -> VocabularyWord:
|
||||
async def search_words(
|
||||
query: str, lang: str = "en", limit: int = 20, offset: int = 0,
|
||||
) -> List[VocabularyWord]:
|
||||
"""Full-text search for words."""
|
||||
"""Full-text search for words. Uses trigram similarity if available, else ILIKE."""
|
||||
pool = await get_pool()
|
||||
col = "english" if lang == "en" else "german"
|
||||
async with pool.acquire() as conn:
|
||||
rows = await conn.fetch(
|
||||
f"""
|
||||
SELECT * FROM vocabulary_words
|
||||
WHERE lower({col}) LIKE $1 OR {col} % $2
|
||||
ORDER BY similarity({col}, $2) DESC, lower({col})
|
||||
LIMIT $3 OFFSET $4
|
||||
""",
|
||||
f"%{query.lower()}%", query, limit, offset,
|
||||
)
|
||||
# Try trigram search first, fall back to ILIKE
|
||||
try:
|
||||
rows = await conn.fetch(
|
||||
f"""
|
||||
SELECT * FROM vocabulary_words
|
||||
WHERE lower({col}) LIKE $1 OR {col} % $2
|
||||
ORDER BY similarity({col}, $2) DESC, lower({col})
|
||||
LIMIT $3 OFFSET $4
|
||||
""",
|
||||
f"%{query.lower()}%", query, limit, offset,
|
||||
)
|
||||
except Exception:
|
||||
rows = await conn.fetch(
|
||||
f"""
|
||||
SELECT * FROM vocabulary_words
|
||||
WHERE lower({col}) LIKE $1
|
||||
ORDER BY lower({col})
|
||||
LIMIT $2 OFFSET $3
|
||||
""",
|
||||
f"%{query.lower()}%", limit, offset,
|
||||
)
|
||||
return [_row_to_word(r) for r in rows]
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user