fix: 搜索 tag 过滤改用 cast(ARRAY(Uuid)),杜绝 asyncpg 把 ARRAY[$n] 推断成 text[] 导致 uuid[] && text[] 500(根因在 year_counts 子查询复用 conditions)
This commit is contained in:
@@ -4,7 +4,7 @@ import logging
|
|||||||
import re
|
import re
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
from sqlalchemy import String, and_, case, cast, exists, func, literal_column, not_, or_, select, text
|
from sqlalchemy import ARRAY, String, Uuid, and_, case, cast, exists, func, literal_column, not_, or_, select, text
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
from sqlalchemy.ext.asyncio import AsyncSession
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
@@ -506,9 +506,11 @@ class AdvancedSearchEngine:
|
|||||||
child_conds = [GlobalTag.path.like(f"{p}%") for p in paths]
|
child_conds = [GlobalTag.path.like(f"{p}%") for p in paths]
|
||||||
children = (await db.execute(select(GlobalTag.id).where(or_(*child_conds)))).scalars().all()
|
children = (await db.execute(select(GlobalTag.id).where(or_(*child_conds)))).scalars().all()
|
||||||
all_tag_ids.update(children)
|
all_tag_ids.update(children)
|
||||||
uids = list(all_tag_ids)
|
uids = [_uuid.UUID(u) if isinstance(u, str) else u for u in all_tag_ids]
|
||||||
from sqlalchemy.dialects.postgresql import array as _pg_array, UUID as _pg_uuid
|
# 显式 cast 到 ARRAY(Uuid):不依赖 _pg_array 的参数类型推断(asyncpg prepared
|
||||||
conditions.append(GlobalLiterature.tag_ids.overlap(_pg_array(uids, type_=_pg_uuid())))
|
# statement 会把 ARRAY[$n] 推断成 text[],导致 uuid[] && text[] 500)。cast 后
|
||||||
|
# 编译产物必带 ::uuid[],杜绝推断漂移。
|
||||||
|
conditions.append(GlobalLiterature.tag_ids.overlap(cast(uids, ARRAY(Uuid))))
|
||||||
|
|
||||||
# 发表类型(PG JSONB contains)
|
# 发表类型(PG JSONB contains)
|
||||||
if pub_types:
|
if pub_types:
|
||||||
|
|||||||
Reference in New Issue
Block a user