从 Wagtail 迁移到 Astro(五):数据同步与脚本化
· 约 9 分钟阅读
Last updated on

从 Wagtail 迁移到 Astro(五):数据同步与脚本化

作者: Alex Xiang


本文是「Wagtail 迁移 Astro」系列的第五篇,介绍如何用脚本把线上 Wagtail 的数据与媒体同步到本地,并导入为 Astro 的 Markdown 文件,形成可重复执行的流程。

一、同步脚本要做什么

  1. 从服务器拉取:Wagtail 使用的 SQLite 数据库、media/original_images/ 等媒体目录。
  2. 写入本地:放到项目内的 legacy-wagtail/(或约定目录),不污染 src/content/blog/ 的现有结构。
  3. 可重复、可配置:通过配置文件记录主机、路径、认证,支持多次执行以做增量或全量更新。

二、同步脚本设计要点

2.1 配置与安全

  • 将服务器地址、用户名、路径、密码或密钥路径放在 配置文件(如 config/deploy.local.json),并加入 .gitignore,避免敏感信息进库。
  • 使用 SSH + SCP/rsyncParamiko 等库执行远程拷贝;大文件可考虑 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 数据

  • 使用 sqlite3SQLAlchemy 连接本地拷贝的 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 幂等与覆盖策略

  • 可按 sluglegacyId 决定是覆盖还是跳过,避免误删手写新文章。
  • 建议导入脚本只覆盖 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 解析一致。

五、小结

通过 syncimport 两个脚本,把 Wagtail 的数据与媒体同步到本地并转换为 Astro 内容,既能保留历史内容,又便于重复执行和后续维护。

本系列文章(一)为什么迁移与选型 · (二)迁移的几个阶段 · (三)添加新文章 · (四)上线 · (五)数据同步与脚本化(本文) · (六)主题与功能打磨