在Python与FastAPI中处理Pydantic模型的null类型partner字段报错问题
解决Pydantic模型处理null partner字段的问题
问题背景
在Python+FastAPI项目中,你编写了交易数据处理代码与Pydantic模型,test_data中某条交易的partner字段为null,尽管已在模型中将partner定义为Optional[dict] = None,但实例化AllTransaction时仍抛出错误,需要实现对null类型partner字段的正常解析。
业务代码
test_data = { "transactions": [{ "id": 5494, "specific_wallet_id": 2079, "evaluation_process_transaction_id": 5229, "transaction_type": "Earn", "points": 9, "created_at": "2022-09-20T16:14:19.000+05:30", "updated_at": "2022-09-20T16:14:19.000+05:30", "custom_wallet_transaction_id": "null", "order_meta_data": {}, "points_validity": "2023-09-20T00:00:00.000+05:30", "points_status": "Active", "transaction_amount": 450.0, "transaction_at": "2022-09-20T16:14:18.000+05:30", "tnx_status": "Successful", "current_points": 9, "programme_id": 4, "customer_id": 1, "reason_code": "Earn", "channel": "app", "order_id": "1", "transaction_references": "null", "points_value": 9.0, "issuer": { "id": 1, "name": "oo", "code": "oo", "image_url": "null" }, "partner": null }, { "id": 5486, "specific_wallet_id": 2079, "evaluation_process_transaction_id": 5221, "transaction_type": "Earn", "points": 9, "created_at": "2022-09-20T15:46:15.000+05:30", "updated_at": "2022-09-20T15:46:15.000+05:30", "custom_wallet_transaction_id": "null", "order_meta_data": {}, "points_validity": "2023-09-20T00:00:00.000+05:30", "points_status": "Active", "transaction_amount": 450.0, "transaction_at": "2022-09-20T15:46:14.000+05:30", "tnx_status": "Successful", "current_points": 9, "programme_id": 4, "customer_id": 2189, "reason_code": "Earn", "channel": "app", "order_id": "uuu", "transaction_references": "null", "points_value": 9.0, "issuer": { "id": 1, "name": "oo", "code": "ooo", "image_url": "null" }, "partner": { "id": 1, "name": "qq", "code": "qq", "image_url": "https://d157777v0iph40..net///offers/avis.jpg" } } ], "success": "true", "error": "null" } results=[] results.extend( [ AllTransaction( issuer_id=Config.evaluation_issuer_id, issuer_name="", issuer_logo="", wallet_id=o["specific_wallet_id"], partner=o["partner"], points=o["points"], points_value_in_currency=( o["points"] * 1 ), transaction_at=o["transaction_at"], transaction_id=o["id"], transaction_type=o["transaction_type"], transaction_meta={ "order_id": o["order_id"], "channel": o["channel"], "order_meta_data": o["order_meta_data"], }, transaction_name=o["transaction_type"], ) for o in test_data["transactions"] ] ) return TransactionResponse(results=results)
Pydantic模型代码
from typing import Optional, datetime from pydantic import BaseModel class TransactionDetailsPartner(BaseModel): partner: Optional[dict] = None class TransactionDetails(BaseModel): points: int points_value_in_currency: float transaction_id: int transaction_at: datetime transaction_type: str transaction_meta: Optional[dict] transaction_name: Optional[TransactionType] class TransactionDetailsIssuer(BaseModel): issuer_id: int issuer_name: str issuer_logo: str wallet_id: int class AllTransaction(TransactionDetails, TransactionDetailsIssuer, TransactionDetailsPartner): pass
核心原因分析
报错本质是数据类型不匹配:
- 若test_data中的
null是字符串类型(比如接口返回JSON未正确解析,导致null转为字符串"null"),Pydantic无法将字符串转为dict类型,触发验证错误。 - 直接在Python字典中写
null属于语法错误,推测实际场景中是JSON解析后的字符串"null"或其他非None空值。
解决方案
方案1:预处理输入数据,统一转为Python的None
在实例化模型前,遍历交易数据,将partner字段的异常空值转为None:
for o in test_data["transactions"]: # 匹配所有需要转为None的情况:字符串"null"、空字典、None if o.get("partner") in ("null", None, {}): o["partner"] = None
方案2:修改Pydantic模型,添加字段验证器自动处理空值
利用Pydantic的前置验证器,在模型解析阶段自动将字符串"null"或其他空值转为None:
from pydantic import validator class TransactionDetailsPartner(BaseModel): partner: Optional[dict] = None @validator('partner', pre=True) def convert_null_to_none(cls, value): # 处理字符串"null"、None、空字典 if value == "null" or value is None or value == {}: return None return value
方案3:确保JSON数据正确解析为Python类型
如果test_data来自JSON字符串,使用json.loads()加载时,JSON中的null会自动转为Python的None,避免手动处理:
import json # 假设原始数据是JSON格式字符串 raw_json = '{"transactions": [{"partner": null}, ...]}' test_data = json.loads(raw_json)
内容的提问来源于stack exchange,提问作者user18578733
相关产品推荐
相关产品推荐

