本文档记录本项目每年从 PDF/图片整理上海中考招生计划、成绩,并导入 MySQL 表 kylx365_db.MPS_Score 的需求、步骤和注意事项。
当前已完成 2026 年“计划”中的 1、2、3:自主招生、名额到区、名额到校。
每年需要处理两大类数据。
一、计划
二、成绩
2026 年当前状态:
目标数据库:kylx365_db
核心表:
MPS_School:学校表,所有学校相关信息以此表为准。MPS_Score:计划与成绩表,所有导入结果写入此表。常用参照查询:
SELECT *
FROM kylx365_db.MPS_School
WHERE SchoolType1 = '高中';
SELECT *
FROM kylx365_db.MPS_Score
WHERE ScoreYear = '2025'
AND ScoreType = '名额到校'
AND DistrictID = 1;
数据库连接信息不要写入 README 或提交到仓库。当前脚本里使用本机已有配置和 PyMySQL 驱动连接,后续最好抽成单独的本地配置文件或环境变量。
1 黄浦区
2 徐汇区
3 长宁区
4 静安区
5 普陀区
6 虹口区
7 杨浦区
8 闵行区
9 宝山区
10 嘉定区
11 浦东新区
12 金山区
13 松江区
14 青浦区
15 奉贤区
16 崇明区
计划类导入一般只写计划数,不写成绩。
通用字段规则:
ScoreYear:年份,例如 2026ScoreType:自主招生、名额到区、名额到校、1-15志愿DistrictID:对应区 IDSchoolTarget:高中学校 MPS_School.ID,以字符串写入SchoolFullName:必须使用高中 ID 对应的 MPS_School.SchoolFullNamePlanNum:计划人数ScoreTotal、Score1、Score2、Score3、Score4:计划导入时填 0ScoreTotalDifferenceValue:计划导入时填 0PlanNumDifferenceValue:当前计划数减去上一年同维度计划数OrderID:当前计划导入填 0SchoolNumber、SchoolNumber2:当前计划导入填空字符串SchoolOfGraduation1:当前计划导入填 "0"名额到校额外规则:
SchoolOfGraduation:初中学校 MPS_School.IDSchoolFullNameJunior:必须使用初中 ID 对应的 MPS_School.SchoolFullNameScoreYear + ScoreType + DistrictID + SchoolOfGraduation + SchoolTarget 理解。SchoolFullNameJunior 或 SchoolFullName。自主招生额外规则:
1学科2体育3艺术4国际(本市)5国际(非本市)SchoolTargetRemark2 可参考上一年同学校同类别备注;体育/艺术通常沿用“市级优秀体育学生”“市级艺术骨干学生”等说明。名额到区额外规则:
SchoolOfGraduation = 0SchoolFullNameJunior = NULLSchoolTargetRemark = ""每一类数据都按以下流程做:
MPS_Score 总行数、总计划数、分区汇总。MPS_School 后,再运行补录脚本,只补缺失行,并刷新问题清单。重要原则:
MPS_School,再重新匹配导入。优先级:
SchoolFullName 匹配。SchoolShortName、SchoolOtherName 匹配。学校名称常见问题:
本次经验:
SchoolOtherName 很适合放改名后的现名或曾用名。脚本分为三类:主流程脚本、公共解析/补录脚本、2026 一次性补充脚本。后续年度工作时,主流程和公共脚本可以复制改年份;一次性补充脚本主要用于追溯 2026 的特殊处理,不建议直接运行到新年份。
自主招生:
import_mps_score_2026.pyScoreType = '自主招生'。名额到区:
import_mps_score_quota_2026.py--dry-run。import_mps_score_quota_manual_2026.py 做手工/OCR 补充。名额到校:
research_mps_score_school_quota_2026.py已支持编号匹配、全称/简称/别名匹配、括号内“现名”匹配、同区唯一包含式匹配。
import_mps_score_school_quota_2026.py
主导入脚本,读取 16 个区名额到校 PDF。
支持 --dry-run。
解析不确定的数据写入 mps_score_school_quota_2026_problems.json。
import_mps_score_school_quota_supplement_2026.py
用于补充处理徐汇、嘉定等表格/OCR特殊区。
import_mps_score_school_quota_hongkou_2026.py
用于处理虹口图片读图后的结构化数据。
fix_mps_score_school_quota_problems_2026.py
当 MPS_School 中新增/修正学校后,重新解析问题区并补插当前能匹配的数据。
会跳过数据库中已存在的 DistrictID + SchoolOfGraduation + SchoolTarget 组合。
会刷新 mps_score_school_quota_2026_problems.json,只保留仍未解决的问题。
2026 一次性补充脚本:
import_mps_score_quota_manual_2026.py:用于 2026 名额到区图片/OCR特殊区的手工补录,不是新年份通用入口。import_mps_score_school_quota_hongkou_2026.py:用于 2026 虹口名额到校图片读图后的手工矩阵导入,不是新年份通用入口。import_mps_score_school_quota_supplement_2026.py:包含 2026 徐汇手工矩阵和嘉定特殊 PDF 解析;其中 collect_jiading 目前仍被 fix_mps_score_school_quota_problems_2026.py 引用,所以不要单独删除。生成物:
__pycache__/ 和 *.pyc 是 Python 运行缓存,不属于业务数据或脚本,已在主仓库 .gitignore 中忽略。计划/自主招生:
ScoreYear = 2026ScoreType = 自主招生计划/名额到区:
ScoreYear = 2026ScoreType = 名额到区计划/名额到校:
ScoreYear = 2026ScoreType = 名额到校mps_score_school_quota_2026_problems.json 已清空2026 名额到校最终分区汇总:
| DistrictID | 区 | 行数 | 计划数 |
|---|---|---|---|
| 1 | 黄浦区 | 217 | 996 |
| 2 | 徐汇区 | 221 | 899 |
| 3 | 长宁区 | 63 | 418 |
| 4 | 静安区 | 271 | 1102 |
| 5 | 普陀区 | 179 | 736 |
| 6 | 虹口区 | 80 | 488 |
| 7 | 杨浦区 | 144 | 707 |
| 8 | 闵行区 | 460 | 1290 |
| 9 | 宝山区 | 348 | 1076 |
| 10 | 嘉定区 | 130 | 612 |
| 11 | 浦东新区 | 1259 | 2082 |
| 12 | 金山区 | 56 | 355 |
| 13 | 松江区 | 190 | 779 |
| 14 | 青浦区 | 93 | 725 |
| 15 | 奉贤区 | 131 | 345 |
| 16 | 崇明区 | 50 | 223 |
总量:
SELECT COUNT(*) AS c, SUM(PlanNum) AS total
FROM MPS_Score
WHERE ScoreYear = '2026'
AND ScoreType = '名额到校';
分区:
SELECT DistrictID, COUNT(*) AS c, SUM(PlanNum) AS total
FROM MPS_Score
WHERE ScoreYear = '2026'
AND ScoreType = '名额到校'
GROUP BY DistrictID
ORDER BY DistrictID;
检查某区上一年参照:
SELECT *
FROM MPS_Score
WHERE ScoreYear = '2025'
AND ScoreType = '名额到校'
AND DistrictID = 1
ORDER BY ID;
查初中学校名称:
SELECT ID, DistrictID, SchoolNumber, SchoolFullName, SchoolShortName, SchoolOtherName
FROM MPS_School
WHERE SchoolType1 = '初中'
AND (
SchoolFullName LIKE '%学校名关键词%'
OR SchoolShortName LIKE '%学校名关键词%'
OR SchoolOtherName LIKE '%学校名关键词%'
);
把脚本从 2026 复制到新年份后,至少检查这些常量:
YEARPREVIOUS_YEARBASE_DIR导入前必须确认目标年份目标类型没有已有数据,或脚本明确支持跳过/补录。
不要为了重新跑脚本而删除数据库旧数据,除非明确确认要重做且已备份。
计划/1-15 志愿:
ScoreType、字段、维度和差值计算。成绩导入:
ScoreTotal、Score1、Score2、Score3、Score4 等字段,不能沿用计划类全部填 0 的规则。