如何在SQLAlchemy中验证JSON与ARRAY类型数据?
用SQLAlchemy实现字段类型的强制校验
针对JSON类型的_meta字段
SQLAlchemy 1.4及以上版本的JSON类型自带schema参数,直接用它就能强制校验字段必须为字典类型,不用自己写额外验证逻辑:
from sqlalchemy import Column, JSON class YourModel(Base): __tablename__ = "your_table" _meta = Column(JSON(schema={"type": "object"}))
当你传入整数、列表这类非字典数据时,ORM层面会直接抛出ValidationError,根本到不了数据库那一步。
针对ARRAY(Text)类型的_context字段
默认情况下ARRAY(Text)会接受任何可迭代对象,但不会校验元素类型。要强制只能存字符串数组,有两种简便方式:
方式一:数据库层面的CHECK约束
直接给字段加CheckConstraint,以PostgreSQL为例(ARRAY类型主要在PG里使用):
from sqlalchemy import Column, ARRAY, Text, CheckConstraint class YourModel(Base): __tablename__ = "your_table" _context = Column(ARRAY(Text), CheckConstraint("ALL(_context IS NOT NULL AND pg_typeof(_context) = 'text[]')"))
数据库会直接拦截不符合要求的数据,不过这个约束语法要适配你使用的数据库(比如MySQL写法不一样)。
方式二:ORM层面的轻量类型封装
用SQLAlchemy的TypeDecorator做个简单封装,在赋值时自动校验每个元素:
from sqlalchemy import ARRAY, Text from sqlalchemy.sql.type_api import TypeDecorator class StrictStringArray(TypeDecorator): impl = ARRAY(Text) def process_bind_param(self, value, dialect): if value is not None and not all(isinstance(item, str) for item in value): raise ValueError("_context的所有元素必须是字符串") return value class YourModel(Base): __tablename__ = "your_table" _context = Column(StrictStringArray)
这种方式在ORM层就会立刻报错,不用等数据库返回,代码也很简洁,算不上自定义复杂验证逻辑,只是用了SQLAlchemy的标准扩展机制。
总结
_meta字段直接用JSON(schema={"type": "object"})就能实现强制字典校验,零自定义代码;_context字段选数据库约束或轻量类型封装都可以,都不用写复杂的验证逻辑,完全基于SQLAlchemy本身的功能。
内容的提问来源于stack exchange,提问作者KZiovas
相关产品推荐
相关产品推荐

