FastAPI结合pgvector与SQLModel查询时报错Unknown PG numeric type:24664的解决咨询
看起来你遇到的这个Unknown PG numeric type: 24664错误,本质是SQLAlchemy(SQLModel基于它实现ORM)没能正确识别pgvector的vector类型对应的PostgreSQL OID(24664正是pgvector类型的OID),导致在结果集映射(比如查询返回模型对象、执行session.refresh时)无法完成类型转换。结合你插入时去掉session.refresh就正常的情况,我们可以从以下几个方向解决:
1. 先确保pgvector扩展和类型注册正确
首先确认你的PostgreSQL数据库已经启用了pgvector扩展,然后在初始化数据库连接时,显式注册pgvector的类型到SQLAlchemy中:
from sqlalchemy import create_engine from pgvector.sqlalchemy import register_vector from sqlmodel import Session # 创建引擎时注册vector类型 engine = create_engine("postgresql://your_user:your_password@your_host/your_db") register_vector(engine) # 后续创建Session时使用这个引擎 def get_session(): with Session(engine) as session: yield session
这个操作会让SQLAlchemy明确识别pgvector的类型,自动完成数据库类型和Python类型的转换。
2. 调整模型的字段定义
你当前的模型定义中,vector字段用了List[float]作为类型,搭配sa_column=Vector(1536),可以尝试直接将字段类型指定为pgvector的Vector类型,让SQLModel更明确地识别:
from pgvector.sqlalchemy import Vector from sqlmodel import SQLModel, Field from uuid import UUID, uuid4 class Record(SQLModel, table=True): id: UUID = Field(default_factory=uuid4, primary_key=True) text: str = Field(default=None) # 直接使用Vector作为字段类型 vector: Vector = Field(default=None, sa_column=Vector(1536))
之后在需要将vector转为Python列表时,可以调用.tolist()方法,比如db_record.vector.tolist()。
3. 规避自动类型转换的临时方案
如果暂时无法完成类型注册,也可以像插入时那样,避免直接返回/操作SQLModel对象,而是手动转换为字典处理:
def create_or_update_record(session: Session, record: RecordCreate): db_record = session.exec( select(Record).where(Record.id == record.id) ).first() if db_record: # 手动更新字段,避免ORM自动处理vector类型 db_record.text = record.text db_record.vector = record.vector session.commit() # 返回字典而非模型对象 return { "id": db_record.id, "text": db_record.text, "vector": db_record.vector.tolist() if db_record.vector else None } else: new_record = Record(**record.dict()) session.add(new_record) session.commit() return dict(new_record)
这种方式跳过了SQLAlchemy对vector字段的自动结果处理,也就不会触发类型识别错误。
4. 检查版本兼容性
最后确认你的依赖版本是否匹配:
- pgvector的Python包版本建议在
0.2.0以上 - SQLModel版本建议使用
0.0.16及以上(确保和SQLAlchemy 1.4+兼容) - SQLAlchemy版本最好是
1.4.x系列(SQLModel暂不兼容2.0+的部分特性)
尝试以上方案后,应该能解决查询和更新时的类型识别错误。
备注:内容来源于stack exchange,提问作者Saeed Esmaili

