Cloudflare Durable Objects 改用 SQLite 與 exports:新舊 Worker 怎麼安全設定
Cloudflare Durable Objects 現在有兩件容易混在一起的事:新 namespace 要使用 SQLite storage,而新的 exports 設定可取代傳統 migrations 管理 class 的建立、重新命名與刪除。兩者都很有用,但不能把它理解成「把既有 KV class 的 storage 改成 sqlite 就完成升級」。
先記住結論:新 class 使用 SQLite;既有 class 先辨識原本 backend,再選擇保留 migrations 或規劃轉為 exports。storage backend 一旦 provisioned,不能原地切換。
新 Worker:從 exports 與 SQLite 開始
Cloudflare 目前的文件建議以 exports 宣告 Durable Object class。這個設定描述目前應存在的 class,而不是維護一串歷史 migration tag。
{ "durable_objects": { "bindings": [ { "name": "ROOM", "class_name": "Room" } ] }, "exports": { "Room": { "type": "durable-object", "storage": "sqlite" } }}部署時使用 wrangler deploy。Cloudflare 會首次 provision namespace,後續 deploy 則拿程式碼、exports 與既有 provisioned state 做 reconciliation。SQLite-backed Durable Objects 可繼續使用 key-value API,也能使用 SQL 與 point-in-time recovery;不必為了選 SQLite 立刻把所有資料存取改成 SQL。
既有 migrations 不要硬改 storage
傳統設定通常是:
[[migrations]]tag = "v1"new_classes = ["Room"]new_classes 代表 legacy KV backend;new_sqlite_classes 則代表 SQLite backend。舊 Worker 可以繼續使用 migrations,並不需要因為 exports 出現就立即改寫。
若要轉換,先列出目前仍在程式碼中 export 的 class,並依最初 migration 判斷每一個 namespace 的 backend。轉成 exports 時,SQLite class 寫 storage: "sqlite",既有 KV class 寫 storage: "legacy-kv"。這項轉換本身不搬資料,但 exports 與 migrations 不能同時存在;第一次以 exports 部署後,也不能再切回舊 migrations 流程。
最容易踩到的三個限制
| 限制 | 實際意思 |
|---|---|
| backend 不可原地變更 | 將既有 namespace 的 legacy-kv 改為 sqlite 會得到 storage_type_mismatch;真正切換需刪除並重新 provision,資料會遺失。 |
| lifecycle 只能透過 deploy | wrangler versions upload 不會套用 Durable Object lifecycle 改動;有 exports 時它會直接失敗。 |
| lifecycle 變更不可 gradual rollout | class 的 rename、delete、transfer 在 control plane 是原子操作;不能靠 gradual deployment 降低這類變更的風險。 |
因此,若你的目標是「既有 KV 資料搬到 SQLite」,目前應把它當成資料遷移專案,而不是一行設定檔改動。先備份與定義資料複製、切流、驗證、回復策略;Cloudflare 說明中也將既有 KV 到 SQLite 的自動 migration 列為未來路徑,不應假設已經可用。
發布前最小檢查清單
- 每個 class 的 backend 是否能從既有 migration 或部署記錄確認?
- 新 class 是否明確宣告
storage: "sqlite"? - 設定檔是否只保留
exports或migrations其中一種? - 是否用
wrangler deploy而非versions upload套用 lifecycle? - delete、rename、transfer 前是否已備份資料,並讀過 reconciliation output?
新專案直接採用 SQLite 與 exports 會比較乾淨;舊專案則要把相容性與資料存續放在「設定寫法漂亮」之前。
參考資料:
Cloudflare Changelog:以 exports 宣告 Durable Object lifecycle
回報錯字、失效連結,或告訴我你想看的延伸主題。