marshmallow中如何校验记录集合内指定字段的唯一性?
目前可以通过 marshmallow 原生的自定义校验机制实现列表内指定字段的唯一性校验,是当前社区通用的标准实现方式,无需依赖额外扩展。
场景1:列表嵌套在对象字段中
可通过 @validates_schema 装饰器实现schema级校验:
from marshmallow import Schema, fields, validates_schema, ValidationError # 单条记录的schema定义 class ItemSchema(Schema): id = fields.Int(required=True) stuff = fields.Str(required=True) # 列表容器的schema定义 class ItemListSchema(Schema): items = fields.List(fields.Nested(ItemSchema), required=True) @validates_schema def validate_unique_id(self, data, **kwargs): seen_ids = set() duplicate_ids = set() for item in data["items"]: item_id = item["id"] if item_id in seen_ids: duplicate_ids.add(item_id) seen_ids.add(item_id) if duplicate_ids: raise ValidationError(f"存在重复的id值:{', '.join(map(str, duplicate_ids))}")
场景2:顶层直接接收数组
可直接给List字段绑定自定义校验器:
from marshmallow import fields, ValidationError def validate_unique_id(items): id_list = [item["id"] for item in items] if len(id_list) != len(set(id_list)): raise ValidationError("列表中存在重复的id值") # 定义顶层数组schema item_list_schema = fields.List(fields.Nested(ItemSchema), validate=validate_unique_id)
通用封装(支持任意字段校验)
如果需要复用校验逻辑,可以封装成通用的校验器生成函数:
def unique_field_validator(field_name: str): def validator(items): value_list = [item[field_name] for item in items] if len(value_list) != len(set(value_list)): raise ValidationError(f"列表中存在重复的{field_name}值") return validator # 使用时直接传入要校验的字段名即可 item_list_schema = fields.List(fields.Nested(ItemSchema), validate=unique_field_validator("id"))
使用你给出的示例数据进行校验时,上述实现会自动识别到重复的id=2,抛出对应的校验错误,符合需求。
内容的提问来源于stack exchange,提问作者tjb
相关产品推荐
相关产品推荐

