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

如何在SQLModel中使用Pydantic的HttpUrl存储至PostgreSQL

解决SQLModel中Pydantic HttpUrl类型存入PostgreSQL的适配问题

问题背景

使用SQLModel 0.0.22、Pydantic 2.10.3、PostgreSQL 14.15,尝试将Pydantic的HttpUrl类型以字符串形式存入数据库,模型代码如下:

class Source(SQLModel, table=True):
    id: UUID | None = Field(default_factory=uuid4, primary_key=True)
    url: HttpUrl = Field(sa_type=AutoString)

执行时触发错误:

sqlalchemy.exc.ProgrammingError: (psycopg.ProgrammingError) cannot adapt type 'HttpUrl' using placeholder '%s' (format: AUTO)

问题原因

SQLModel向数据库写入数据时,直接传递了Pydantic的HttpUrl对象,而psycopg无法将该对象直接适配为PostgreSQL的字符串类型,导致报错。

解决方案

方法一:自定义SQLAlchemy类型(推荐,兼容性强)

创建自定义SQLAlchemy类型,负责HttpUrl与字符串的双向转换:

from sqlalchemy import TypeDecorator, String
from pydantic import HttpUrl, parse_obj_as

class HttpUrlType(TypeDecorator):
    impl = String
    cache_ok = True

    def process_bind_param(self, value, dialect):
        # 存入数据库时,将HttpUrl转为字符串
        return str(value) if value else None

    def process_result_value(self, value, dialect):
        # 查询返回时,将字符串转回HttpUrl对象
        return parse_obj_as(HttpUrl, value) if value else None

修改模型,使用自定义类型:

class Source(SQLModel, table=True):
    id: UUID | None = Field(default_factory=uuid4, primary_key=True)
    url: HttpUrl = Field(sa_type=HttpUrlType)

方法二:通过Pydantic序列化器转换

利用Pydantic序列化器,在写入数据库前自动将HttpUrl转为字符串:

from pydantic import HttpUrl, PlainSerializer

class Source(SQLModel, table=True):
    id: UUID | None = Field(default_factory=uuid4, primary_key=True)
    url: HttpUrl = Field(
        sa_type=AutoString,
        # 序列化时将HttpUrl转为字符串
        serializer=PlainSerializer(lambda x: str(x), return_type=str)
    )

验证

创建实例时传入符合URL格式的字符串,Pydantic会自动验证为HttpUrl对象;存入数据库时自动转为字符串存储;查询返回时,SQLModel会将字符串重新解析为HttpUrl对象,同时保留Pydantic的验证逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 04:22:14