Aller au contenu principal

Stockage Cloudflare D1

L'implémentation du stockage Cloudflare D1 fournit une solution de base de données SQL serverless fondée sur Cloudflare D1, qui prend en charge les opérations relationnelles et la cohérence transactionnelle.

Observabilité non prise en charge

Le stockage Cloudflare D1 ne prend pas en charge le domaine de l'observabilité. Les traces de MastraStorageExporter ne peuvent pas être conservées dans D1, et les fonctionnalités d'observabilité de Studio ne fonctionneront pas si D1 est votre seul Provider de stockage. Pour activer l'observabilité, utilisez le stockage composite afin d'acheminer les données d'observabilité vers un Provider pris en charge tel que ClickHouse.

Limite de taille des lignes

Cloudflare D1 impose une taille maximale de ligne de 1 Mio. Cette limite peut être dépassée lors du stockage de messages contenant des pièces jointes encodées en base64, telles que des images. Consultez Gérer les pièces jointes volumineuses pour découvrir des solutions de contournement, notamment le téléversement des pièces jointes vers un stockage externe.

Installation
Lien direct vers Installation

npm install @mastra/cloudflare-d1@latest

Utilisation
Lien direct vers Utilisation

Utiliser avec le CloudflareDeployer de Mastra
Lien direct vers Utiliser avec le CloudflareDeployer de Mastra

La méthode standard pour utiliser D1Store avec Mastra sur Cloudflare consiste à employer CloudflareDeployer. Importez env depuis cloudflare:workers et initialisez D1Store directement dans new Mastra({...}).

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',
},
],
}),
})
remarque

Lorsque vous utilisez import { env } from 'cloudflare:workers', D1Store doit être initialisé directement dans new Mastra({...}), sans être extrait dans une variable au niveau du module. Vous pouvez également initialiser D1Store dans le gestionnaire fetch une fois env disponible. Consultez la référence de CloudflareDeployer pour plus de détails.

Utiliser dans un Worker Cloudflare sans routes HTTP
Lien direct vers Utiliser dans un Worker Cloudflare sans routes HTTP

Si vous souhaitez appeler Mastra directement dans un Worker (par exemple, pour exécuter un agent ou déclencher un workflow) sans servir de routes HTTP, vous n'avez pas besoin de CloudflareDeployer. Accédez à la liaison D1 depuis le paramètre env du Worker et appelez Mastra par programmation.

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 })
},
}

Utiliser avec l'API REST
Lien direct vers Utiliser avec l'API REST

Pour les environnements autres que les Workers (Node.js, fonctions serverless, etc.), utilisez l'approche fondée sur l'API REST :

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
})

Configuration de Wrangler
Lien direct vers Configuration de Wrangler

Ajoutez la liaison de la base de données D1 à votre fichier wrangler.toml :

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

Ou dans wrangler.jsonc :

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

Paramètres
Lien direct vers Paramètres

binding?:

D1Database
Liaison Workers de Cloudflare D1 (pour l'environnement d'exécution Workers)

accountId?:

string
Identifiant du compte Cloudflare (pour l'API REST)

databaseId?:

string
Identifiant de la base de données Cloudflare D1 (pour l'API REST)

apiToken?:

string
Jeton de l'API Cloudflare (pour l'API REST)

tablePrefix?:

string
Préfixe facultatif pour tous les noms de tables (utile pour isoler les environnements)

Remarques supplémentaires
Lien direct vers Remarques supplémentaires

Gestion du schéma
Lien direct vers Gestion du schéma

L'implémentation du stockage gère automatiquement la création et la mise à jour du schéma. Elle crée les tables suivantes :

  • threads : stocke les fils de conversation
  • messages : stocke les messages individuels
  • metadata : stocke les métadonnées supplémentaires des fils et des messages

Initialisation
Lien direct vers Initialisation

Lorsque vous transmettez le stockage à la classe Mastra, init() est appelée automatiquement avant toute opération de stockage :

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')
},
}

Si vous utilisez le stockage directement sans Mastra, vous devez appeler explicitement init() afin de créer les tables :

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')
},
}
attention

Si init() n'est pas appelée, les tables ne seront pas créées et les opérations de stockage échoueront silencieusement ou lèveront des erreurs.

Transactions et cohérence
Lien direct vers Transactions et cohérence

Cloudflare D1 fournit des garanties transactionnelles pour les opérations sur une seule ligne. Plusieurs opérations peuvent être exécutées comme une seule unité de travail indivisible.

Création des tables et migrations
Lien direct vers Création des tables et migrations

Les tables sont créées automatiquement lors de l'initialisation du stockage (et peuvent être isolées par environnement à l'aide de l'option tablePrefix), mais les modifications avancées du schéma nécessitent une migration manuelle et une planification minutieuse. Il peut notamment s'agir d'ajouter des colonnes ou de modifier les types de données et les index afin d'éviter toute perte de données.