6.1 KiB
6.1 KiB
正确的多主键删除逻辑实现
🎯 问题分析
您指出了一个关键问题:我之前的实现逻辑是错误的。
❌ 错误的逻辑(之前)
基于schema的items.type判断:
- items.type == "string" → 单主键(字符串数组)
- items.type == "object" → 多主键(对象数组)
✅ 正确的逻辑(现在)
基于identityId列表长度判断:
- len(identityId) == 1 → 单主键(字符串数组)
- len(identityId) > 1 → 多主键(对象数组)
🔧 实现修正
1. DMSEndpoint增强
添加了identity_id_list属性来存储完整的identityId配置:
class DMSEndpoint(BaseEndpoint):
def __init__(self, ..., identity_id_list: Optional[List[str]] = None):
# ...
self.identity_id_list = identity_id_list or []
2. DMS API解析增强
在解析DMS API时,根据identityId长度自动生成正确的删除schema:
# 获取identityId列表
identity_id_list = model.get("identityId")
if isinstance(identity_id_list, list) and len(identity_id_list) > 1:
# 多主键:生成对象数组schema
delete_request_body_schema = {
"type": "object",
"properties": {
"version": {"type": "string"},
"data": {
"type": "array",
"items": {
"type": "object",
"properties": {pk1: schema1, pk2: schema2, ...},
"required": [pk1, pk2, ...]
}
}
}
}
else:
# 单主键:生成字符串数组schema
delete_request_body_schema = {
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {"type": "string"}
}
}
}
3. CRUD Stage逻辑修正
删除请求体构建现在直接基于identityId列表:
def _build_delete_request_body(self, scenario, pk_name, pk_value, create_payload):
delete_op = scenario.get('delete')
identity_id_list = getattr(delete_op, 'identity_id_list', [])
if len(identity_id_list) > 1:
# 多主键:使用对象列表
return self._build_multi_key_delete_body(identity_id_list, pk_name, pk_value, create_payload)
else:
# 单主键:使用字符串列表
return {"data": [pk_value]}
📊 支持的配置和格式
配置示例
单主键配置
{
"identityId": ["proppantId"]
}
生成的删除格式:
{
"data": ["proppant_001", "proppant_002"]
}
双主键配置
{
"identityId": ["projectId", "surveyId"]
}
生成的删除格式:
{
"version": "1.0.0",
"data": [
{"projectId": "项目1_ID", "surveyId": "工区1_ID"},
{"projectId": "项目2_ID", "surveyId": "工区2_ID"}
]
}
三主键配置
{
"identityId": ["wellId", "layerId", "sampleId"]
}
生成的删除格式:
{
"version": "1.0.0",
"data": [
{"wellId": "井001", "layerId": "层001", "sampleId": "样本001"},
{"wellId": "井002", "layerId": "层002", "sampleId": "样本002"}
]
}
🎯 核心改进
1. 准确的业务逻辑
- 直接基于DMS的identityId配置
- 不再依赖schema结构推测
- 准确反映业务意图
2. 自动schema生成
- 解析器根据identityId自动生成正确的删除schema
- 单主键自动生成字符串数组schema
- 多主键自动生成对象数组schema
3. 智能字段处理
- 从创建负载中自动提取相关主键
- 为缺失的主键字段生成默认值
- 支持批量删除(生成多个对象)
4. 优雅回退
- 当identityId为空时回退到简单格式
- 确保删除操作始终可以执行
🔄 工作流程
1. DMS API解析
↓
2. 读取identityId配置
↓
3. 判断主键数量
├─ len(identityId) == 1 → 生成字符串数组schema
└─ len(identityId) > 1 → 生成对象数组schema
↓
4. 创建DMSEndpoint(包含identity_id_list)
↓
5. CRUD Stage执行
↓
6. 根据identity_id_list长度构建删除请求体
├─ 单主键 → {"data": ["key1", "key2"]}
└─ 多主键 → {"version": "1.0.0", "data": [{"key1": "val1", "key2": "val2"}]}
📝 测试验证
所有测试场景均通过:
- ✅ 单主键删除(identityId长度=1)
- ✅ 多主键删除(identityId长度=2)
- ✅ 三主键删除(identityId长度=3)
- ✅ 空identityId回退处理
- ✅ 缺失字段自动生成
💡 使用示例
DMS配置
{
"name": "projectSurvey",
"model": {
"identityId": ["projectId", "surveyId"],
"properties": {
"projectId": {"type": "string"},
"surveyId": {"type": "string"},
"relationName": {"type": "string"}
}
}
}
自动生成的删除端点
{
"path": "/api/dms/test/v1/projectSurvey",
"method": "DELETE",
"requestBody": {
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"version": {"type": "string"},
"data": {
"type": "array",
"items": {
"type": "object",
"properties": {
"projectId": {"type": "string"},
"surveyId": {"type": "string"}
},
"required": ["projectId", "surveyId"]
}
}
}
}
}
}
}
}
生成的删除请求
{
"version": "1.0.0",
"data": [
{"projectId": "项目1_ID", "surveyId": "工区1_ID"},
{"projectId": "项目1_ID", "surveyId": "工区2_ID"}
]
}
🎉 总结
通过这次修正,DMS合规性测试工具现在能够:
- 正确理解业务配置:基于identityId而不是schema推测
- 自动生成正确格式:单主键用字符串数组,多主键用对象数组
- 支持任意主键组合:1个、2个、3个或更多主键
- 智能处理缺失字段:自动生成默认值
- 提供批量删除支持:生成多个删除对象
这确保了测试数据完全符合DMS系统的实际业务规则和API设计!