跳至主要內容

Cloudflare D1 儲存空間

Cloudflare D1 儲存空間實作採用 Cloudflare D1,提供支援關聯式操作與交易一致性的 serverless SQL 資料庫解決方案。

不支援可觀測性

Cloudflare D1 儲存空間不支援 observability domainMastraStorageExporter 的 Trace 無法持久化至 D1;若 D1 是唯一的儲存 Provider,Studio 的可觀測性功能也無法運作。若要啟用可觀測性,請使用複合儲存空間,將可觀測性資料路由至 ClickHouse 等受支援的 Provider。

資料列大小限制

Cloudflare D1 規定每個資料列最大為 1 MiB。儲存包含圖片等 base64 編碼附件的訊息時,可能超過此限制。如需包含將附件上傳至外部儲存空間等替代做法,請參閱處理大型附件

安裝
「安裝」的直接連結

npm install @mastra/cloudflare-d1@latest

使用方式
「使用方式」的直接連結

搭配 Mastra CloudflareDeployer 使用
「搭配 Mastra CloudflareDeployer 使用」的直接連結

在 Cloudflare 上搭配 Mastra 使用 D1Store 的標準方式是使用 CloudflareDeployer。請從 cloudflare:workers 匯入 env,並在 new Mastra({...}) 內以 inline 方式初始化 D1Store

src/mastra/index.ts
import { env } from 'cloudflare:workers'
import { D1Store } from '@mastra/cloudflare-d1'
import { Mastra } from '@mastra/core'
import { CloudflareDeployer } from '@mastra/deployer-cloudflare'

export const mastra = new Mastra({
storage: new D1Store({ binding: env.DB }),
deployer: new CloudflareDeployer({
name: 'my-worker',
d1_databases: [
{
binding: 'DB',
database_name: 'your-database-name',
database_id: 'your-database-id',
},
],
}),
})
備註

使用 import { env } from 'cloudflare:workers' 時,必須在 new Mastra({...}) 內以 inline 方式初始化 D1Store,不可將它抽取為模組層級變數。另一種方式是在 env 可用後,於 fetch handler 內初始化 D1Store。詳情請參閱 CloudflareDeployer 參考資料

在沒有 HTTP route 的 Cloudflare Worker 中使用
「在沒有 HTTP route 的 Cloudflare Worker 中使用」的直接連結

若要在 Worker 中直接呼叫 Mastra(例如執行 Agent 或觸發 Workflow),但不提供 HTTP route,便不需要 CloudflareDeployer。請從 worker 的 env 參數存取 D1 binding,並以程式呼叫 Mastra。

import { D1Store } from '@mastra/cloudflare-d1'
import { Mastra } from '@mastra/core'

type Env = {
DB: D1Database
}

export default {
async fetch(request: Request, env: Env, ctx: ExecutionContext) {
const mastra = new Mastra({
storage: new D1Store({ binding: env.DB }),
})

const agent = mastra.getAgent('my-agent')
const result = await agent.generate('Hello')

return Response.json({ text: result.text })
},
}

搭配 REST API 使用
「搭配 REST API 使用」的直接連結

對於非 Workers 環境(Node.js、serverless function 等),請使用 REST API 方式:

import { D1Store } from '@mastra/cloudflare-d1'

const storage = new D1Store({
accountId: process.env.CLOUDFLARE_ACCOUNT_ID!, // Cloudflare Account ID
databaseId: process.env.CLOUDFLARE_D1_DATABASE_ID!, // D1 Database ID
apiToken: process.env.CLOUDFLARE_API_TOKEN!, // Cloudflare API Token
tablePrefix: 'dev_', // Optional: isolate tables per environment
})

Wrangler 設定
「Wrangler 設定」的直接連結

將 D1 database binding 新增至 wrangler.toml

[[d1_databases]]
binding = "DB"
database_name = "your-database-name"
database_id = "your-database-id"

或新增至 wrangler.jsonc

{
"d1_databases": [
{
"binding": "DB",
"database_name": "your-database-name",
"database_id": "your-database-id",
},
],
}

參數
「參數」的直接連結

binding?:

D1Database
Cloudflare D1 Workers binding(用於 Workers runtime)

accountId?:

string
Cloudflare Account ID(用於 REST API)

databaseId?:

string
Cloudflare D1 Database ID(用於 REST API)

apiToken?:

string
Cloudflare API Token(用於 REST API)

tablePrefix?:

string
所有資料表名稱的選用 prefix(適合用於隔離環境)

其他注意事項
「其他注意事項」的直接連結

Schema 管理
「Schema 管理」的直接連結

儲存空間實作會自動處理 schema 的建立與更新,並建立下列資料表:

  • threads:儲存對話 thread
  • messages:儲存個別訊息
  • metadata:儲存 thread 與訊息的其他 metadata

初始化
「初始化」的直接連結

將 storage 傳入 Mastra 類別時,系統會在進行任何儲存操作前自動呼叫 init()

import { Mastra } from '@mastra/core'
import { D1Store } from '@mastra/cloudflare-d1'

type Env = {
DB: D1Database
}

// In a Cloudflare Worker
export default {
async fetch(request: Request, env: Env, ctx: ExecutionContext) {
const storage = new D1Store({
binding: env.DB,
})

const mastra = new Mastra({
storage, // init() is called automatically
})

// Your handler logic here
return new Response('Success')
},
}

若不透過 Mastra 而直接使用 storage,必須明確呼叫 init() 來建立資料表:

import { D1Store } from '@mastra/cloudflare-d1'

type Env = {
DB: D1Database
}

// In a Cloudflare Worker
export default {
async fetch(request: Request, env: Env, ctx: ExecutionContext) {
const storage = new D1Store({
id: 'd1-storage',
binding: env.DB,
})

// Required when using storage directly
await storage.init()

// Access domain-specific stores via getStore()
const memoryStore = await storage.getStore('memory')
const thread = await memoryStore?.getThreadById({ threadId: '...' })

return new Response('Success')
},
}
警告

若未呼叫 init(),系統不會建立資料表,儲存操作將會無聲失敗或擲回錯誤。

交易與一致性
「交易與一致性」的直接連結

Cloudflare D1 為單一資料列操作提供交易保證。多項操作可作為不可分割的單一工作單元執行。

建立資料表與 migration
「建立資料表與 migration」的直接連結

storage 初始化時會自動建立資料表(並可使用 tablePrefix 選項依環境隔離),但進階 schema 變更需要手動 migration 與周全規劃。例如新增欄位,或變更資料型別與索引時,都必須避免資料遺失。