· 约 9 分钟阅读
Last updated on
从 Wagtail 迁移到 Astro(五):数据同步与脚本化
本文是「Wagtail 迁移 Astro」系列的第五篇,介绍如何用脚本把线上 Wagtail 的数据与媒体同步到本地,并导入为 Astro 的 Markdown 文件,形成可重复执行的流程。
一、同步脚本要做什么
- 从服务器拉取:Wagtail 使用的 SQLite 数据库、
media/original_images/等媒体目录。 - 写入本地:放到项目内的
legacy-wagtail/(或约定目录),不污染src/content/blog/的现有结构。 - 可重复、可配置:通过配置文件记录主机、路径、认证,支持多次执行以做增量或全量更新。
二、同步脚本设计要点
2.1 配置与安全
- 将服务器地址、用户名、路径、密码或密钥路径放在 配置文件(如
config/deploy.local.json),并加入.gitignore,避免敏感信息进库。 - 使用 SSH + SCP/rsync 或 Paramiko 等库执行远程拷贝;大文件可考虑 rsync 增量,减少重复传输。
2.2 同步范围
- 数据库:整库拷贝一份到本地,例如
legacy-wagtail/zicodedb。 - 媒体:只同步用到的目录(如
media/original_images/),可先根据库中图片路径统计再拉取,或全量同步一次后增量。
2.3 目录结构示例
project/
config/
deploy.local.json # 本地配置,不提交
legacy-wagtail/
zicodedb # 拷贝的 SQLite
media/
original_images/ # 拷贝的图片
scripts/
sync_legacy.py # 同步脚本
astro-site/
src/content/blog/imported/ # 导入脚本输出
public/uploads/ # 导入时拷贝的图片
配置示例(config/deploy.local.json,勿提交到 Git):
{
"wagtail_host": "user@example.com",
"wagtail_db_path": "/path/on/server/zicodedb",
"wagtail_media_path": "/path/on/server/media",
"local_legacy_dir": "legacy-wagtail"
}
同步时用 rsync 拉取数据库与媒体目录到 local_legacy_dir,再用 Paramiko/SSH 执行远程命令或直接用 rsync over SSH 均可。
三、导入脚本设计要点
3.1 读取 Wagtail 数据
- 使用 sqlite3 或 SQLAlchemy 连接本地拷贝的
zicodedb。 - 查询文章表:标题、slug、发布时间、正文(StreamField JSON)、分类、标签、专栏、作者、头图等。
- StreamField 需按块类型解析:paragraph、markdown、image、heading 等,拼接成最终 Markdown。
3.2 生成 Astro 内容文件
- 每篇文章生成一个
.md文件,放在src/content/blog/imported/。 - Frontmatter 按本站 schema 填写:title、description、pubDate、updatedDate、slug、draft、category、column、authors、tags、heroImage。
- 正文中的图片路径改为站内路径,如
/uploads/original_images/xxx.png,并在导入时把对应文件拷贝到astro-site/public/uploads/original_images/。
3.3 幂等与覆盖策略
- 可按 slug 或 legacyId 决定是覆盖还是跳过,避免误删手写新文章。
- 建议导入脚本只覆盖
imported/下由脚本生成的文件(如按文件名前缀或单独子目录),手写文章放在别处或使用不同命名规则。
四、一键流程示例
在项目根目录可以封装一条命令,例如:
python scripts/sync_legacy.py && python scripts/import_wagtail.py
或使用 Makefile:
sync:
python scripts/sync_legacy.py
import: sync
python scripts/import_wagtail.py
build: import
cd astro-site && pnpm build
这样「拉数据 → 导入 → 构建」可一条龙执行,便于定期从旧站同步或发布前更新。
常见问题:
- StreamField 结构不一致:不同 Wagtail 版本或自定义块可能导致 JSON 结构差异,导入脚本里应对未知块类型做降级(如当普通段落或跳过),并打 log 便于后续补全。
- 图片重复:若多次全量导入,
public/uploads/会累积;可约定「按 legacyId 或 slug 覆盖同文件」或「先清空 imported 再导入」,避免重复拷贝同一张图多份。 - 时区:Wagtail 的
first_published_at等时间字段若为 UTC,写入 frontmatter 时可按需转为本地时间或统一写 ISO 字符串,与 Astro 的pubDate解析一致。
五、小结
通过 sync 与 import 两个脚本,把 Wagtail 的数据与媒体同步到本地并转换为 Astro 内容,既能保留历史内容,又便于重复执行和后续维护。
本系列文章:(一)为什么迁移与选型 · (二)迁移的几个阶段 · (三)添加新文章 · (四)上线 · (五)数据同步与脚本化(本文) · (六)主题与功能打磨