# 正确的多主键删除逻辑实现 ## 🎯 问题分析 您指出了一个关键问题:我之前的实现逻辑是错误的。 ### ❌ 错误的逻辑(之前) ``` 基于schema的items.type判断: - items.type == "string" → 单主键(字符串数组) - items.type == "object" → 多主键(对象数组) ``` ### ✅ 正确的逻辑(现在) ``` 基于identityId列表长度判断: - len(identityId) == 1 → 单主键(字符串数组) - len(identityId) > 1 → 多主键(对象数组) ``` ## 🔧 实现修正 ### 1. DMSEndpoint增强 添加了`identity_id_list`属性来存储完整的identityId配置: ```python 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: ```python # 获取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列表: ```python 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]} ``` ## 📊 支持的配置和格式 ### 配置示例 #### 单主键配置 ```json { "identityId": ["proppantId"] } ``` **生成的删除格式**: ```json { "data": ["proppant_001", "proppant_002"] } ``` #### 双主键配置 ```json { "identityId": ["projectId", "surveyId"] } ``` **生成的删除格式**: ```json { "version": "1.0.0", "data": [ {"projectId": "项目1_ID", "surveyId": "工区1_ID"}, {"projectId": "项目2_ID", "surveyId": "工区2_ID"} ] } ``` #### 三主键配置 ```json { "identityId": ["wellId", "layerId", "sampleId"] } ``` **生成的删除格式**: ```json { "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配置 ```json { "name": "projectSurvey", "model": { "identityId": ["projectId", "surveyId"], "properties": { "projectId": {"type": "string"}, "surveyId": {"type": "string"}, "relationName": {"type": "string"} } } } ``` ### 自动生成的删除端点 ```json { "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"] } } } } } } } } ``` ### 生成的删除请求 ```json { "version": "1.0.0", "data": [ {"projectId": "项目1_ID", "surveyId": "工区1_ID"}, {"projectId": "项目1_ID", "surveyId": "工区2_ID"} ] } ``` ## 🎉 总结 通过这次修正,DMS合规性测试工具现在能够: 1. **正确理解业务配置**:基于identityId而不是schema推测 2. **自动生成正确格式**:单主键用字符串数组,多主键用对象数组 3. **支持任意主键组合**:1个、2个、3个或更多主键 4. **智能处理缺失字段**:自动生成默认值 5. **提供批量删除支持**:生成多个删除对象 这确保了测试数据完全符合DMS系统的实际业务规则和API设计!