演进已部署站点的模式

本页内容

EmDash 把集合、字段和分类法与内容一起存放在数据库中。本指南介绍如何更改这个线上内容模型,同时避免把它与代码部署、首次种子初始化或 EmDash 核心迁移混为一谈。示例使用 Cloudflare D1;同样的区分也适用于每一种数据库适配器。

什么会改变什么

站点会经历四种不同的工作流,每一种影响不同的层:

工作流变化的内容方式
内容编辑条目、媒体、设置管理后台或内容 API
代码部署模板、配置、EmDash 版本wrangler deploy —— 可能会迁移由 EmDash 管理的数据库表
首次引导一切,从空白开始迁移 + 种子文件 + 设置向导,首次启动时自动执行
模式演进集合、字段、分类法针对线上站点使用管理后台或 emdash schema(本页)

种子文件只参与第三行。它的模式和结构只会应用一次,发生在设置向导完成之前的第一次请求时。把修改过的种子文件部署到已有的数据库上不会有任何效果——演进线上站点的模式始终通过管理后台或 API 完成。

在管理后台中更改模式

管理后台是演进已部署站点的主要方式。在管理后台中打开 Content Types,然后添加、编辑或删除集合和字段。更改会立即生效——内容 API、加载器和编辑界面都会在运行时从数据库读取模式。

可用的字段类型、校验规则和控件选项请参阅集合与字段。

更改模式之后,请重新生成模板所使用的 TypeScript 类型。emdash types 命令会从运行中的实例读取模式,因此可以直接指向已部署的站点:

npx emdash types --url https://example.com

通过 CLI 更改模式

emdash schema 命令通过 REST API 与运行中的实例通信,因此它们对已部署站点的使用方式与对本地开发环境完全相同。先用设备流程完成一次认证:

npx emdash login --url https://example.com

你也可以在管理后台的 Settings → API Tokens 下创建 API 令牌,并通过 --token 或 EMDASH_TOKEN 环境变量传入——这对 CI 很有用。

然后使用与本地相同的命令来演进模式:

npx emdash schema add-field posts subtitle --type string --label "Subtitle" --url https://example.com
npx emdash schema remove-field posts legacy_field --url https://example.com
npx emdash schema create projects --label Projects --url https://example.com

这些命令可以放入脚本并提交到仓库,使每个环境都接收到相同的、有顺序的更改。这些命令并不会自动保持幂等:对已存在的对象重复运行 create 或 add-field 可能会失败。请用 emdash schema list 或 get 检查目标,记录每个环境已完成哪些步骤,并在出现第一个错误时立即停止。

完整的命令列表请参阅 CLI 参考。

保持种子文件同步

构建中嵌入的种子文件决定了全新数据库会初始化成什么样:新的预览环境、灾难恢复重建,或同一站点的第二次部署。如果种子文件仍然描述的是入门博客,而生产环境已经演进成了别的样子,那么每个全新环境启动时用的都是错误的模型。

构建会嵌入按顺序找到的第一个种子文件:.emdash/seed.json、package.json#emdash.seed 中指定的路径,或 seed/seed.json。如果这些都不存在,就会嵌入内置的默认种子(入门博客模型),同时 astro dev 会记录一条警告。

演进已部署站点的模式之后,请把线上的模型导出回你的仓库。emdash export-seed 读取本地 SQLite 文件,而 wrangler d1 export 可以从已部署的 D1 数据库生成这样的文件:

npx wrangler d1 export emdash-db --remote --output=./prod.sql
sqlite3 prod.db < prod.sql
npx emdash export-seed --database prod.db > .emdash/seed.json

导出的种子包含线上站点的设置、集合、分类法、菜单、重定向、小组件区域和 sections。添加 --with-content 可以一并包含条目。请把更新后的 .emdash/seed.json 与依赖新模式的代码一起提交,这样全新环境启动时总能得到代码能够理解的模型。

在预览环境中演练更改

破坏性的模式更改(删除字段、重构集合)最安全的做法,是先在生产环境的一份可随时丢弃的副本上演练。

  1. 创建一个单独的预览 D1 数据库,并让 Wrangler 把它添加到 preview 环境:

    npx wrangler d1 create emdash-db-preview \
      --binding DB --env preview --update-config

    确认 env.preview.d1_databases 中包含新数据库的名称和 UUID。绑定不会从顶层的 Wrangler 配置继承。

  2. 导出生产数据,然后通过预览环境的 DB 绑定导入该 SQL:

    npx wrangler d1 export emdash-db --remote --output=./prod.sql
    npx wrangler d1 execute DB --env preview --remote --file=./prod.sql
  3. 构建项目并部署到预览环境,然后针对预览 URL 执行模式更改:

    npm run build
    npx wrangler deploy --env preview
    npx emdash schema remove-field posts legacy_field --url https://preview.example.com
  4. 验证公开页面、管理后台表单、生成的类型,以及任何读取被更改字段的模板。重新做一份生产数据库备份,然后只在生产环境中运行一次同样的命令。

从失误中恢复

  • 误删了一个字段。 该列及其数据已从线上数据库中消失。请从 D1 的 Time Travel 时间点备份中恢复,或者重新添加该字段,并从更早的 wrangler d1 export 中恢复它的值。
  • 全新环境用错误的模型完成了引导。 嵌入的种子已经过时或缺失。请更新 .emdash/seed.json(参见保持种子文件同步),重新构建,并让部署指向一个空数据库,以再次完成引导。
  • 模式和模板不一致。 部署和模式更改是相互独立的,因此要有意识地安排顺序:增量式的模式更改(新集合、新的可选字段)先进行,然后再部署使用它们的代码。对于删除操作,先部署不再使用该字段的代码,再删除字段。