You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MongoDB Binary字段转Pydantic模型遇编码及类型错误的问询

解决方案:MongoDB二进制图片字段转Pydantic模型

问题根源

  • 用bytes定义Pydantic字段时,Pydantic会默认尝试将二进制数据解码为Unicode字符串,而图片的二进制流包含非合法Unicode字符,触发UnicodeDecodeError。
  • 用bson.Binary并开启arbitrary_types_allowed时,MongoDB驱动返回的图片数据是原生bytes类型,而非bson.Binary实例,导致类型不匹配错误。

可行解决方案

1. 自定义Pydantic字段类型(推荐,通用型)

创建一个自定义字段,自动处理bytes与bson.Binary的转换,无需在查询或模型中额外处理:

from pydantic import GetCoreSchemaHandler
from pydantic_core import core_schema
from bson import Binary

class BinaryImageField(bytes):
    @classmethod
    def __get_pydantic_core_schema__(cls, source_type, handler: GetCoreSchemaHandler) -> core_schema.CoreSchema:
        return core_schema.no_info_after_validator_function(
            cls.validate,
            core_schema.bytes_schema(),
        )

    @classmethod
    def validate(cls, value):
        if isinstance(value, bytes):
            return Binary(value)
        elif isinstance(value, Binary):
            return value
        raise ValueError("字段必须为bytes或bson.Binary类型")

在Pydantic模型中使用该字段:

from pydantic import BaseModel

class ImageRecord(BaseModel):
    id: str
    image: BinaryImageField

    class Config:
        arbitrary_types_allowed = True

2. 查询MongoDB时转换类型

在从MongoDB读取数据后,手动将bytes类型的图片字段转换为bson.Binary实例:

from pymongo import MongoClient
from bson import Binary
from your_models import ImageRecord

# 连接MongoDB
client = MongoClient("mongodb://localhost:27017/")
db = client["your_database"]
collection = db["your_collection"]

# 查询并转换数据
image_records = []
for doc in collection.find():
    if isinstance(doc.get("image"), bytes):
        doc["image"] = Binary(doc["image"])
    image_records.append(ImageRecord(**doc))

3. 使用Pydantic前置验证器

通过BeforeValidator装饰器,在模型验证前自动将bytes转换为bson.Binary:

from pydantic import BaseModel, BeforeValidator
from bson import Binary

def convert_bytes_to_binary(value):
    if isinstance(value, bytes):
        return Binary(value)
    return value

class ImageRecord(BaseModel):
    id: str
    image: Binary = BeforeValidator(convert_bytes_to_binary)

    class Config:
        arbitrary_types_allowed = True

额外注意事项

  • 确保MongoDB中存储的图片数据是二进制类型(而非Base64字符串),否则需要调整字段处理逻辑。
  • 如果使用Pydantic v1版本,自定义字段需改用validator装饰器实现,而非__get_pydantic_core_schema__。

内容的提问来源于stack exchange,提问作者F. F.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 12:03:14