GCP Postgres+PGVector插入向量报错:为何期望字符串?
解决asyncpg插入Postgres向量字段报错的问题
问题根源
你用到的vector类型是pgvector扩展提供的自定义类型,asyncpg默认没有内置对该类型的序列化逻辑,因此会将其当作普通用户自定义类型处理,要求传入字符串格式,而非直接接受list或numpy数组。
两种解决方法
方法1:手动将向量转为字符串格式
把list或np.array转换成Postgres pgvector支持的字符串形式——用方括号包裹、元素以逗号分隔:
# 处理list类型向量 vector_list = [0.1, 0.2, ..., 0.1536] vector_str = f"[{','.join(map(str, vector_list))}]" # 处理numpy数组类型向量 import numpy as np vector_np = np.array([0.1, 0.2, ..., 0.1536]) vector_str = f"[{','.join(map(str, vector_np.tolist()))}]" # 插入时传入转换后的字符串 await conn.execute( "INSERT INTO your_table (contentVector, other_column) VALUES ($1, $2)", vector_str, "其他字段内容" )
方法2:给asyncpg注册vector类型转换器
提前注册pgvector类型的序列化与反序列化逻辑,之后就能直接传入list或np.array:
import asyncpg import numpy as np async def register_vector_type(conn): # 查询vector类型的OID oid = await conn.fetchval("SELECT oid FROM pg_type WHERE typname = 'vector'") if not oid: raise ValueError("未检测到pgvector扩展,请先安装") # 定义序列化函数:将list/np.array转为pgvector识别的格式 def serialize_vector(vector): if isinstance(vector, np.ndarray): vector = vector.tolist() return f"[{','.join(map(str, vector))}]" # 定义反序列化函数(从数据库读取向量时使用) def deserialize_vector(value): value_str = value.decode('utf-8').strip('[]') return np.array([float(x) for x in value_str.split(',')]) # 注册类型编解码器 await conn.set_type_codec( oid, encoder=serialize_vector, decoder=deserialize_vector, format='text' ) # 使用示例 async def main(): conn = await asyncpg.connect("你的数据库连接字符串") await register_vector_type(conn) # 直接传入list插入 await conn.execute( "INSERT INTO your_table (contentVector) VALUES ($1)", [0.1, 0.2, ..., 0.1536] ) # 直接传入numpy数组插入 await conn.execute( "INSERT INTO your_table (contentVector) VALUES ($1)", np.random.rand(1536) ) await conn.close()
额外注意
- 确保已在Postgres数据库中安装pgvector扩展,执行
CREATE EXTENSION IF NOT EXISTS vector; - 若使用SQLAlchemy等ORM,需对应配置vector类型的处理逻辑,核心思路仍是将向量转为pgvector可识别的格式
内容的提问来源于stack exchange,提问作者Daniel
相关产品推荐
相关产品推荐

