在执行 POST /api/data_resource/ddl/parse 接口时,出现错误:
'int' object does not support item assignment
文件: app/api/data_resource/routes.py
函数: ddl_identify() (行 614-683)
错误行: 654 和 672
# 第654行
ddl_list[table_name]["exist"] = False
# 第672行
ddl_list[table_name]["exist"] = exists
代码假设 ddl_list[table_name] 始终是一个字典对象,但实际上:
DDLParser.parse_ddl() 方法使用 LLM 解析 SQL,返回的 JSON 结构可能不符合预期ddl_list[table_name] 是否为字典类型就直接进行赋值操作ddl_list[table_name] 是整数、字符串或其他非字典类型时,尝试使用 [] 操作符赋值会失败| 情况 | ddl_list[table_name] 的类型 |
错误 |
|---|---|---|
| LLM 返回格式错误 | int, str, list |
✗ 类型不支持 item assignment |
| 解析失败 | None |
✗ NoneType 不支持 item assignment |
| 正常情况 | dict |
✓ 正常 |
添加类型检查,确保只对字典类型的值进行赋值操作。
修复前:
# 首先为所有表设置默认的exist状态
for table_name in table_names:
ddl_list[table_name]["exist"] = False
修复后:
# 首先为所有表设置默认的exist状态
for table_name in table_names:
# 确保 ddl_list[table_name] 是字典类型
if isinstance(ddl_list[table_name], dict):
ddl_list[table_name]["exist"] = False
else:
logger.warning(f"表 {table_name} 的值不是字典类型: {type(ddl_list[table_name])}")
修复前:
# 更新存在的表的状态
for record in table_results:
table_name = record["name"]
exists = record["exists"]
if table_name in ddl_list:
ddl_list[table_name]["exist"] = exists
修复后:
# 更新存在的表的状态
for record in table_results:
table_name = record["name"]
exists = record["exists"]
# 确保表名存在且对应的值是字典类型
if table_name in ddl_list and isinstance(ddl_list[table_name], dict):
ddl_list[table_name]["exist"] = exists
✅ 在赋值前检查类型,避免类型错误 ✅ 对非字典类型给出警告日志,便于问题排查
✅ 能够处理 LLM 返回不一致的情况 ✅ 不会因为个别表的数据格式错误而导致整个请求失败
✅ 添加警告日志记录异常类型 ✅ 便于调试和监控
| 特性 | 修复前 | 修复后 |
|---|---|---|
| 类型检查 | ❌ 无 | ✅ 有 |
| 错误处理 | ❌ 崩溃 | ✅ 优雅降级 |
| 日志记录 | ❌ 无 | ✅ 警告日志 |
| 用户体验 | ❌ 500 错误 | ✅ 返回部分结果 |
在 parse_ddl 返回后立即验证数据结构:
def validate_ddl_structure(ddl_list):
"""验证DDL解析结果的结构"""
if not isinstance(ddl_list, dict):
return False, "ddl_list 必须是字典类型"
for table_name, table_data in ddl_list.items():
if not isinstance(table_data, dict):
return False, f"表 {table_name} 的数据必须是字典类型"
# 检查必要字段
if "meta" not in table_data:
return False, f"表 {table_name} 缺少 meta 字段"
if not isinstance(table_data["meta"], list):
return False, f"表 {table_name} 的 meta 必须是列表类型"
return True, "验证通过"
# 使用
ddl_list = parser.parse_ddl(sql_content)
is_valid, message = validate_ddl_structure(ddl_list)
if not is_valid:
logger.error(f"DDL结构验证失败: {message}")
return jsonify(failed(message))
在 DDLParser 中添加响应格式标准化:
def parse_ddl(self, sql_content):
"""解析DDL语句,返回标准化的结构"""
# ... 现有代码 ...
# 标准化返回结果
if isinstance(parsed_result, dict):
# 确保每个表的数据都是字典类型
for table_name in list(parsed_result.keys()):
if not isinstance(parsed_result[table_name], dict):
logger.warning(f"移除非字典类型的表数据: {table_name}")
del parsed_result[table_name]
return parsed_result
def test_ddl_identify_with_invalid_structure():
"""测试处理无效结构的情况"""
# 模拟返回无效结构
invalid_ddl = {
"table1": {"name_zh": "表1", "meta": []},
"table2": 123, # 错误:整数类型
"table3": "invalid" # 错误:字符串类型
}
# 验证能够正常处理
result = process_ddl_list(invalid_ddl)
assert "table1" in result
assert result["table1"]["exist"] == False
# table2 和 table3 应该被跳过
try:
ddl_list = parser.parse_ddl(sql_content)
except Exception as e:
logger.error(f"DDL解析失败: {str(e)}")
# 尝试使用备用解析方法
ddl_list = fallback_parse_ddl(sql_content)
{
"users": {
"name_zh": "用户表",
"meta": [...]
}
}
✅ 应该正常添加 exist 字段
{
"users": 123
}
✅ 应该记录警告日志,跳过该表
{
"users": "invalid"
}
✅ 应该记录警告日志,跳过该表
{
"users": null
}
✅ 应该记录警告日志,跳过该表
{
"users": {
"name_zh": "用户表",
"meta": [...]
},
"orders": 456,
"products": {
"name_zh": "产品表",
"meta": [...]
}
}
✅ 应该正常处理 users 和 products,跳过 orders
# 使用 curl 测试
curl -X POST http://localhost:5500/api/data_resource/ddl/parse \
-H "Content-Type: application/json" \
-d '{"sql": "CREATE TABLE users (id INT, name VARCHAR(100));"}'
# 检查返回结果和日志
监控以下警告日志:
表 {table_name} 的值不是字典类型: {type}
如果频繁出现,说明 LLM 返回格式不稳定,需要优化提示词。
| 文件 | 修改内容 |
|---|---|
app/api/data_resource/routes.py |
添加类型检查,修复 item assignment 错误 |
app/core/llm/ddl_parser.py |
无修改(建议未来优化) |
执行 DDL 解析接口时出现 'int' object does not support item assignment 错误。
代码未验证 ddl_list[table_name] 的类型就直接进行字典操作。
在赋值前添加 isinstance() 类型检查,确保只对字典类型进行操作。
✅ 错误修复: 不再出现类型错误 ✅ 健壮性提升: 能够处理异常数据结构 ✅ 日志完善: 便于问题排查和监控 ✅ 用户体验改善: 即使部分数据异常也能返回有效结果
修复时间: 2025-11-03
修复文件: app/api/data_resource/routes.py (行 653-680)
状态: ✅ 已完成