国保数据库已收录5052条全国重点文物保护单位数据,但存在以下问题:
| 问题 | 说明 |
|---|---|
| 调整记录分散 | 238条合并/归入记录存储在JSON文件中,未写入数据库 |
| 最新名称缺失 | 文物改名后,数据库只有原名称,无最新名称 |
| 历史信息不完整 | 详情页无法展示文物的调整历史 |
| 搜索受限 | 无法通过调整记录内容搜索文物 |
核心目标:将 merge_adjustments.json 中的238条调整记录批量导入数据库,更新文物的 Content 和 LatestName 字段。
{
"第四批": {
"year": "1996",
"type": "归入",
"count": 12,
"data": [
{
"name": "镇朔楼",
"time": "明",
"location": "河北省张家口市",
"note": "归入清远楼"
}
]
}
}
| 类型 | 示例 | 说明 |
|---|---|---|
| 归入 | "归入清远楼" | A文物归入B文物 |
| 并入 | "并入第六批全国重点文物保护单位牡丹江边墙" | A文物并入B文物 |
| 合并+改名 | "与第五批全国重点文物保护单位古荥冶铁遗址合并,名称:荥阳故城" | A和B合并,新名称为C |
最初的理解错误:
镇朔楼 → 归入 → 清远楼
↓
错误:查找"镇朔楼",更新镇朔楼
正确的业务逻辑:
镇朔楼 → 归入 → 清远楼
↓
正确:查找"清远楼"(被归入的目标文物),更新清远楼的Content字段
记录:清远楼 ← 镇朔楼归入于此
app/national_sites/批量导入调整数据.pydef parse_target_name(note):
"""从 note 字段中提取目标文物名称"""
# 情况1:有"名称:"(合并改名)
if '名称:' in note:
new_name = note.split('名称:')[1].strip()
# 提取旧名称,去掉批次前缀和连接词
old_name = before_name.replace('与', '').replace('合并', '')
return (old_name, new_name) # 返回(数据库中的旧名称, 新名称)
# 情况2:普通归入/并入
target = note
if target.startswith('归入'):
target = target[2:]
elif target.startswith('并入'):
target = target[2:]
# 去掉批次前缀
for prefix in ['第一批全国重点文物保护单位', ...]:
target = target.replace(prefix, '')
return (target.strip(), None)
1. 备份数据库(带时间戳)
↓
2. 读取 JSON 数据
↓
3. 遍历所有批次的调整记录
↓
4. 对每条记录:
a. 提取目标文物名称(从note字段)
b. 在数据库中查找目标文物
c. 解析或创建 Content JSON
d. 追加调整记录到 adjustments 数组
e. 如果有新名称,更新 LatestName
f. 更新数据库
↓
5. 输出统计报告
冯焕阙的 Content 字段:
{
"adjustments": [
{
"batch": "第五批",
"year": "2001",
"type": "合并",
"source": "冯焕阙",
"note": "冯焕阙 与赵家村汉阙、王家坪汉阙、蒲家湾汉阙、沈府君阙合并,名称:渠县汉阙"
}
]
}
同时设置: LatestName = "渠县汉阙"
现象:最初查找来源文物(如"镇朔楼"),但应该查找目标文物(如"清远楼")
根因:理解错误,调整记录是记录"谁归入到了目标文物",而不是"来源文物被归入"
解决: - 从 note 字段解析目标文物名称 - 处理批次前缀("归入第六批全国重点文物保护单位牡丹江边墙" → "牡丹江边墙") - 在数据库中查找目标文物并更新
现象:"与第五批全国重点文物保护单位古荥冶铁遗址合并,名称:荥阳故城"
需要提取: - 旧名称:古荥冶铁遗址(数据库中的名称) - 新名称:荥阳故城(LatestName)
解决:
# 去掉批次前缀
old_name = old_name.replace('第五批全国重点文物保护单位', '')
# 去掉连接词
old_name = old_name.replace('与', '').replace('合并', '').replace(',', '')
需求:一个文物可能有多次调整记录(如大运河在第七批和第八批都有调整)
解决:
# 读取现有 Content
if content_json:
content_data = json.loads(content_json)
else:
content_data = {'adjustments': []}
# 追加新记录
content_data['adjustments'].append(new_adjustment)
# 写回数据库
cursor.execute('UPDATE ... SET Content = ?', (json.dumps(content_data),))
现象:Content IS NOT NULL 包含空字符串,导致筛选不准确
解决:
-- 修改前
WHERE Content IS NOT NULL
-- 修改后
WHERE Content IS NOT NULL AND Content != ''
需求:在列表中显示文物的最新名称
实现:
<strong>{{ site.NameC }}</strong>
{% if site.LatestName and site.LatestName != site.NameC %}
<span style="color: #e74c3c; margin: 0 4px; font-weight: bold;">→</span>
<strong style="color: #c0392b;">{{ site.LatestName }}</strong>
{% endif %}
效果:
冯焕阙 → 渠县汉阙
↑ 红色箭头 + 红色新名称
需求:美观展示文物的调整历史
实现:
{% if adj.type == '合并' and '名称:' in adj.note %}
<strong>合并后名称:</strong>
<span class="new-name-highlight">{{ adj.note.split('名称:')[1].strip() }}</span>
<p class="adjustment-note">{{ adj.source }} 合并说明</p>
{% elif adj.type == '归入' or adj.type == '并入' %}
<strong>归入/合并至:</strong>{{ adj.note }}
{% endif %}
样式:
.new-name-highlight {
background: #e8f4f8;
color: #2c5f6b;
border: 1px solid #b8e0ed;
padding: 3px 10px;
border-radius: 4px;
}
效果:
📋 调整历史
第五批 2001年 [合并]
━━━━━━━━━━━━━━━━━━━━━━━━
合并后名称:渠县汉阙
冯焕阙 赵家村汉阙、王家坪汉阙、蒲家湾汉阙、沈府君阙
============================================================
导入统计报告
============================================================
总调整记录数: 238
匹配成功: 220
更新成功: 220
更新失败: 0
未匹配总数: 18
⚠️ 未匹配的合并改名类(8 条):
------------------------------------------------------------
来源: 荥阳故城
旧名: 古荥冶铁遗址
新名: 荥阳故城
批次: 第六批
说明: 与第五批全国重点文物保护单位古荥冶铁遗址合并,名称:荥阳故城
⚠️ 未匹配的普通归入/并入类(10 条):
------------------------------------------------------------
- 清远楼 (来源: 镇朔楼, 第四批)
归入清远楼
============================================================
| 功能 | 状态 | 说明 |
|---|---|---|
| 批量导入 | ✓ | 220条成功导入 |
| 最新名称显示 | ✓ | 列表页红色箭头显示 |
| 调整历史展示 | ✓ | 详情页卡片式时间线 |
| 搜索增强 | ✓ | Content字段全文检索 |
| 调整记录列表 | ✓ | 专用路由 /adjusted/ |
当前有18条未匹配记录,可能原因: - 数据库中名称与JSON中的名称不一致 - 目标文物尚未录入数据库 - 批次前缀解析不完整
建议: - 手动核对未匹配列表 - 修正数据库中的文物名称 - 更新 JSON 数据
{"adjustments": [...]} 结构app/national_sites/批量导入调整数据.py — 批量导入脚本app/national_sites/merge_adjustments.json — 调整数据源(238条)app/national_sites/routes.py — 路由(含调整记录查询)app/national_sites/templates/national_sites/list.html — 列表页模板app/national_sites/templates/national_sites/detail.html — 详情页模板national_sites.db — 国保主数据库Content 字段:存储调整历史 JSONLatestName 字段:存储最新名称| 日期 | 版本 | 说明 |
|---|---|---|
| 2026-05-07 | v1.0 | 初始版本,完成批量导入脚本开发 |
| 2026-05-07 | v1.1 | 修正目标文物识别逻辑 |
| 2026-05-07 | v1.2 | 优化合并改名类名称解析 |
| 2026-05-07 | v1.3 | 前端展示优化,实现新名称和调整历史展示 |
总结:通过批量导入脚本,成功将238条国保调整记录导入数据库,实现了文物最新名称显示和调整历史展示。核心技术突破在于正确理解了"目标文物"的业务逻辑,以及处理了多种格式的note字段。前端采用优雅的配色方案,避免了视觉突兀,提升了用户体验。