问题现象与诊断
当开发者使用weaviate.Client.create_object()方法时,最常见的错误之一是属性值类型不匹配。系统会返回类似这样的错误信息:"Property 'age' expected type 'number' but got 'string'"。这种类型不匹配通常发生在以下场景:
- JSON序列化过程中自动类型转换
- 从外部数据源(如CSV)导入未清洗的数据
- 动态语言类型系统导致的隐式转换
- Weaviate类模式(Schema)定义与实际数据不一致
根本原因分析
Weaviate采用强类型模式系统,在创建类(Class)时必须明确定义每个属性的数据类型。常见的数据类型包括:
{
"classes": [{
"class": "Person",
"properties": [
{"name": "name", "dataType": ["text"]},
{"name": "age", "dataType": ["int"]}, # 明确要求整数类型
{"name": "birthDate", "dataType": ["date"]}
]
}]
}
当Python字典中的值与模式定义不符时,就会触发类型校验错误。例如传递"age": "25"(字符串)而非"age": 25(整数)。
解决方案
1. 预处理数据验证
创建自定义验证器,确保数据符合模式要求:
def validate_object(schema: dict, obj: dict) -> dict:
type_map = {
"int": int,
"text": str,
"boolean": bool,
"number": (int, float)
}
validated = {}
for prop, value in obj.items():
expected_type = schema[prop]["dataType"][0]
if not isinstance(value, type_map[expected_type]):
try:
validated[prop] = type_map[expected_type](value)
except (ValueError, TypeError):
raise ValueError(f"无法转换 {prop} 值到 {expected_type}")
else:
validated[prop] = value
return validated
2. 使用Pydantic模型
结合Pydantic实现运行时类型检查:
from pydantic import BaseModel, validator
class PersonModel(BaseModel):
name: str
age: int
@validator('age', pre=True)
def convert_age(cls, v):
return int(v) if str(v).isdigit() else v
person = PersonModel(name="Alice", age="25") # 自动转换类型
client.create_object("Person", person.dict())
3. 模式同步策略
实施模式版本控制,确保客户端与服务端同步:
def ensure_schema(client, current_schema):
remote_schema = client.schema.get()
if remote_schema != current_schema:
client.schema.delete_all()
client.schema.create(current_schema)
高级技巧
对于复杂数据类型处理:
- 日期时间转换:使用
datetime.isoformat()处理日期属性 - 地理坐标:将GeoJSON转换为Weaviate支持的格式
- 数组类型:确保数组元素类型一致
from datetime import datetime
data = {
"eventDate": datetime.now().isoformat(), # 转换为ISO8601字符串
"locations": {
"type": "Point",
"coordinates": [52.3667, 4.8945]
}
}
错误监控建议
建立完善的错误处理机制:
- 记录失败的创建操作及其原始数据
- 实现自动重试机制(带指数退避)
- 使用Sentry等工具监控类型错误
- 定期审计模式与数据的匹配度
通过实施这些解决方案,开发者可以显著减少create_object方法的类型相关错误,提高数据导入的可靠性。