fix: 终审修复——test_case_id 格式校验、modify 空变更报错、异常兜底与文档补充
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -33,6 +33,7 @@
|
|||||||
- `TableDump = {"name": str, "columns": [{"name": str, "type": str}], "rows": [[原始值]], "total_rows": int, "truncated": bool}`
|
- `TableDump = {"name": str, "columns": [{"name": str, "type": str}], "rows": [[原始值]], "total_rows": int, "truncated": bool}`
|
||||||
- `ExpectedQuery = {"columns": [str], "rows": [[原始值]], "total_rows": int, "truncated": bool}`(query 模式)
|
- `ExpectedQuery = {"columns": [str], "rows": [[原始值]], "total_rows": int, "truncated": bool}`(query 模式)
|
||||||
- `ExpectedModify = {"changed_tables": [TableDump, ...]}`(modify 模式,只含执行标准答案后内容有变化的表)
|
- `ExpectedModify = {"changed_tables": [TableDump, ...]}`(modify 模式,只含执行标准答案后内容有变化的表)
|
||||||
|
- 被标准答案 DROP 的表以 `{"dropped": true, "rows": [], "total_rows": 0}` 条目出现(columns 取初始结构);标准答案未改任何表时抛 SQLCaseError
|
||||||
|
|
||||||
- [ ] **Step 1: 在 `sql_runner.py` 末尾追加展示数据生成代码**
|
- [ ] **Step 1: 在 `sql_runner.py` 末尾追加展示数据生成代码**
|
||||||
|
|
||||||
|
|||||||
@@ -44,6 +44,8 @@ SQL 题目前沿用传统题的展示结构:「输入/输出」两段富文本
|
|||||||
|
|
||||||
- query 模式:`expected` 为 `{columns, rows}` 结果集
|
- query 模式:`expected` 为 `{columns, rows}` 结果集
|
||||||
- modify 模式:`expected` 为 `{"changed_tables": [{name, columns, rows, total_rows, truncated}]}`,只含有变化的表
|
- modify 模式:`expected` 为 `{"changed_tables": [{name, columns, rows, total_rows, truncated}]}`,只含有变化的表
|
||||||
|
- modify 模式中被标准答案 DROP 的表以 `{"name", "columns"(原结构), "rows": [], "total_rows": 0, "truncated": false, "dropped": true}` 条目出现,前端渲染为「XX 表已被删除」
|
||||||
|
- modify 模式若标准答案未改动任何表,保存时报错(视为出题配置问题)
|
||||||
|
|
||||||
### 生成逻辑
|
### 生成逻辑
|
||||||
|
|
||||||
|
|||||||
@@ -324,6 +324,8 @@ def build_display(init_sql, ref_sql, mode, *, memory_limit_mb=64):
|
|||||||
_execute_trusted(conn, ref_sql, time.monotonic() + trusted_limit_s, "标准答案执行失败")
|
_execute_trusted(conn, ref_sql, time.monotonic() + trusted_limit_s, "标准答案执行失败")
|
||||||
after = _dump_tables(conn)
|
after = _dump_tables(conn)
|
||||||
changed = {name for name in set(before) | set(after) if before.get(name) != after.get(name)}
|
changed = {name for name in set(before) | set(after) if before.get(name) != after.get(name)}
|
||||||
|
if not changed:
|
||||||
|
raise SQLCaseError(JudgeStatus.SYSTEM_ERROR, "标准答案未修改任何表数据,请检查题目配置")
|
||||||
changed_tables = _dump_display_tables(conn, only=changed)
|
changed_tables = _dump_display_tables(conn, only=changed)
|
||||||
# 被标准答案 DROP 的表已不在库中,用初始展示数据补齐条目(前端据 dropped 提示“表已删除”)
|
# 被标准答案 DROP 的表已不在库中,用初始展示数据补齐条目(前端据 dropped 提示“表已删除”)
|
||||||
existing = {t["name"] for t in changed_tables}
|
existing = {t["name"] for t in changed_tables}
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ class CreateOrEditProblemSerializer(serializers.Serializer):
|
|||||||
input_description = serializers.CharField(allow_blank=True)
|
input_description = serializers.CharField(allow_blank=True)
|
||||||
output_description = serializers.CharField(allow_blank=True)
|
output_description = serializers.CharField(allow_blank=True)
|
||||||
samples = serializers.ListField(child=CreateSampleSerializer(), allow_empty=True)
|
samples = serializers.ListField(child=CreateSampleSerializer(), allow_empty=True)
|
||||||
test_case_id = serializers.CharField(max_length=32)
|
test_case_id = serializers.RegexField(regex=r"^[a-zA-Z0-9]+$", max_length=32)
|
||||||
test_case_score = serializers.ListField(child=CreateTestCaseScoreSerializer(), allow_empty=True)
|
test_case_score = serializers.ListField(child=CreateTestCaseScoreSerializer(), allow_empty=True)
|
||||||
time_limit = serializers.IntegerField(min_value=1, max_value=1000 * 60)
|
time_limit = serializers.IntegerField(min_value=1, max_value=1000 * 60)
|
||||||
memory_limit = serializers.IntegerField(min_value=1, max_value=1024)
|
memory_limit = serializers.IntegerField(min_value=1, max_value=1024)
|
||||||
|
|||||||
@@ -238,7 +238,7 @@ class ProblemBase(APIView):
|
|||||||
if not keys:
|
if not keys:
|
||||||
return "题目没有任何测试点"
|
return "题目没有任何测试点"
|
||||||
input_name = info["test_cases"][keys[0]]["input_name"]
|
input_name = info["test_cases"][keys[0]]["input_name"]
|
||||||
except (KeyError, AttributeError):
|
except (KeyError, AttributeError, TypeError):
|
||||||
return "测试点信息损坏,请重新上传测试点"
|
return "测试点信息损坏,请重新上传测试点"
|
||||||
try:
|
try:
|
||||||
with open(os.path.join(test_case_dir, input_name), encoding="utf-8") as f:
|
with open(os.path.join(test_case_dir, input_name), encoding="utf-8") as f:
|
||||||
|
|||||||
Reference in New Issue
Block a user