Aller au contenu

Astro DB

Astro DB est une base de données SQL entièrement gérée, conçue exclusivement pour Astro. Développez localement ou connectez-vous à une base de données hébergée et gérée sur notre plateforme Astro Studio.

Ajoutez Astro DB à un projet Astro nouveau ou existant (nécessite astro@4.5 ou plus) avec l’intégration @astrojs/db (v0.8.0 ou plus). Astro inclut une commande intégrée astro add pour automatiser ce processus d’installation.

Fenêtre de terminal
npx astro add db

Si vous préférez, vous pouvez installer @astrojs/db manuellement à la place.

Astro DB est une solution complète pour configurer, développer et consulter vos données. Une base de données locale est créée chaque fois que vous lancez astro dev, utilisant LibSQL pour gérer vos données sans avoir besoin de Docker ou d’une connexion réseau.

L’installation de @astrojs/db avec la commande astro add créera un fichier db/config.ts dans votre projet où vous définirez les tables de votre base de données :

db/config.ts
import { defineDb } from 'astro:db';
export default defineDb({
tables: { },
})

Dans Astro DB, les données sont stockées dans des tables SQL. Les tables structurent vos données en lignes et en colonnes, où les colonnes imposent le type de chaque valeur de ligne.

Lorsque vous définissez une table, Astro génère une interface TypeScript pour interroger cette table à partir de votre projet. Le résultat est un support TypeScript complet lorsque vous accédez à vos données avec l’autocomplétion des propriétés et la vérification des types.

Pour configurer une table de base de données individuelle, importez et utilisez les utilitaires defineTable() et column de astro:db.

Cet exemple configure une table Comment avec des colonnes de texte obligatoires pour author et body et la rend disponible pour votre projet à travers l’export defineDb().

db/config.ts
import { defineDb, defineTable, column } from 'astro:db';
const Comment = defineTable({
columns: {
author: column.text(),
body: column.text(),
}
})
export default defineDb({
tables: { Comment },
})
Voir la référence de configuration des tables pour une référence complète des options de table.

Astro DB prend en charge les types de colonnes suivants :

db/config.ts
import { defineTable, column } from 'astro:db';
const Comment = defineTable({
columns: {
// Une chaîne de texte.
author: column.text(),
// Une valeur entière.
likes: column.number(),
// Une valeur vraie ou fausse.
flagged: column.boolean(),
// Valeurs de date et d'heure interrogées sous forme d'Objets JavaScript de type date.
published: column.date(),
// Un objet JSON non typé.
metadata: column.json(),
}
});
Voir la référence des colonnes de la table pour plus de détails.

Les relations entre les tables sont un modèle courant dans la conception des bases de données. Par exemple, une table Blog peut être en relation étroite avec d’autres tables Comment, Author, et Category.

Vous pouvez définir ces tables de relations et les enregistrer dans le schéma de votre base de données à l’aide de colonnes de référence. Pour établir une relation, vous aurez besoin de :

  • Une colonne identifiant de la table référencée. Il s’agit généralement d’une colonne id avec la propriété primaryKey.
  • Une colonne sur la table de base pour stocker l’id référencé. Ceci utilise la propriété references pour établir une relation.

Cet exemple montre que la colonne authorId d’une table Comment fait référence à la colonne id d’une table Author.

db/config.ts
const Author = defineTable({
columns: {
id: column.number({ primaryKey: true }),
name: column.text(),
}
});
const Comment = defineTable({
columns: {
authorId: column.number({ references: () => Author.columns.id }),
body: column.text(),
}
});

En développement, Astro utilisera la configuration de votre base de données pour générer des types locaux en fonction de vos schémas. Ceux-ci seront générés à chaque fois que le serveur de développement sera démarré, et vous permettront d’interroger et de travailler sur la forme de vos données avec la sécurité des types et l’autocomplétion.

Pour ajouter des données de développement pour les tests et le débogage dans votre projet Astro, créez un fichier db/seed.ts. Importez l’objet db et toute table configurée depuis astro:db. Utilisez la fonction db.insert() pour fournir un tableau d’objets de données de ligne de table.

L’exemple suivant définit deux lignes de données de développement pour une table Comment :

db/seed.ts
import { db, Comment } from 'astro:db';
export default async function() {
await db.insert(Author).values([
{ id: 1, name: "Kasim" },
{ id: 2, name: "Mina" },
]);
}

Votre serveur de développement redémarrera automatiquement votre base de données chaque fois que ce fichier changera, régénérant vos types et alimentant vos données de développement à partir de seed.ts.

Vous pouvez interroger votre base de données depuis n’importe quelle page Astro ou endpoint de votre projet en utilisant l’ORM db et le constructeur de requêtes fourni.

import { db } from 'astro:db';

Astro DB comprend un client intégré Drizzle ORM. Il n’y a pas d’installation ou de configuration manuelle requise pour utiliser le client. Le client Astro DB db est automatiquement configuré pour communiquer avec votre base de données (locale ou distante) lorsque vous lancez Astro. Il utilise la définition exacte du schéma de votre base de données pour des requêtes SQL sûres, avec des erreurs TypeScript lorsque vous référencez une colonne ou une table qui n’existe pas.

L’exemple suivant sélectionne toutes les lignes d’une table Comment. Cela renvoie le tableau complet des données de développement provenant de db/seed.ts, qui est alors disponible pour être utilisé dans votre modèle de page :

src/pages/index.astro
---
import { db, Comment } from 'astro:db';
const comments = await db.select().from(Comment);
---
<h2>Commentaires</h2>
{
comments.map(({ author, body }) => (
<article>
<p>Auteur: {author}</p>
<p>{body}</p>
</article>
))
}
Voir la référence API Drizzle select() pour une vue d’ensemble complète.

Pour accepter les entrées de l’utilisateur, comme le traitement des demandes de formulaire et l’insertion de données dans votre base de données hébergée à distance, configurez votre projet Astro pour un rendu à la demande et ajoutez un adaptateur SSR pour votre environnement de déploiement.

Cet exemple insère une ligne dans une table Comment sur la base d’une requête POST de formulaire analysée :

src/pages/index.astro
---
import { db, Comment } from 'astro:db';
if (Astro.request.method === 'POST') {
// parse form data
const formData = await Astro.request.formData();
const author = formData.get('author');
const content = formData.get('content');
if (typeof author === 'string' && typeof content === 'string') {
// insérer les données du formulaire dans la table Comment
await db.insert(Comment).values({ author, content });
}
}
// affiche la nouvelle liste des commentaires sur chaque demande
const comments = await db.select().from(Comment);
---
<form method="POST" style="display: grid">
<label for="author">Auteur</label>
<input id="author" name="author" />
<label for="content">Contenu</label>
<textarea id="content" name="content"></textarea>
<button type="submit">Envoyer</button>
</form>
<!--render `comments`-->

Vous pouvez également interroger votre base de données à partir d’un point de terminaison de l’API. Cet exemple supprime une ligne d’une table Comment par le paramètre id :

src/pages/api/comments/[id].ts
import type { APIRoute } from "astro";
import { db, Comment } from 'astro:db';
export const DELETE: APIRoute = async (ctx) => {
await db.delete(Comment).where({ id: ctx.params.id });
return new Response(null, { status: 204 });
}

Voir la [référence API Drizzle insert()] (https://orm.drizzle.team/docs/insert) pour une vue d’ensemble complète.

Pour rechercher les résultats d’une table en fonction d’une propriété spécifique, utilisez les options Drizzle pour les sélections partielles. Par exemple, ajoutez un appel à .where() à votre requête select() et passez la comparaison que vous voulez faire.

L’exemple suivant recherche toutes les lignes d’une table Comment qui contiennent l’expression “Astro DB”. Utilisez l’opérateur like() pour vérifier si une phrase est présente dans le body :

src/pages/index.astro
---
import { db, Comment, like } from 'astro:db';
const comments = await db.select().from(Comment).where(
like(Comment.body, '%Astro DB%')
);
---

Tous les utilitaires Drizzle permettant de construire des requêtes sont exposés à partir du module astro:db. Cela inclut :

import { eq, gt, count, sql } from 'astro:db';

Vous pouvez interroger des données liées provenant de plusieurs tables à l’aide d’une liaison SQL. Pour créer une requête de liaison, ajoutez un opérateur de liaison à votre déclaration db.select(). Chaque fonction accepte une table à l’origine de la liaison et une condition pour faire correspondre les lignes entre les deux tables.

Cet exemple utilise une fonction innerJoin() pour faire la liaison entre les auteurs de Commentaires et leurs informations Author sur la base de la colonne authorId. Cette fonction retourne un tableau d’objets avec chaque ligne Author et Comment comme propriétés de premier niveau :

src/pages/index.astro
---
import { db, eq, Comment, Author } from 'astro:db';
const comments = await db.select()
.from(Comment)
.innerJoin(Author, eq(Comment.authorId, Author.id));
---
<h2>Commentaires</h2>
{
comments.map(({ Author, Comment }) => (
<article>
<p>Auteur: {Author.name}</p>
<p>{Comment.body}</p>
</article>
))
}

Voir la référence de liaison Drizzle pour tous les opérateurs de liaison disponibles et les options de configuration.

Toutes les requêtes de bases de données distantes sont effectuées sous la forme d’une requête réseau. Vous pouvez avoir besoin de regrouper les requêtes en une seule transaction lorsque vous effectuez un grand nombre de requêtes, ou de procéder à des retours en arrière automatiques en cas d’échec d’une requête.

Cet exemple permet de lancer plusieurs lignes en une seule requête à l’aide de la méthode db.batch() :

db/seed.ts
import { db, Author, Comment } from 'astro:db';
export default async function () {
let queries;
// Envoyez 100 exemples de commentaires dans votre base de données distante
// avec une seule demande de réseau.
for (let i = 0; i < 100; i++) {
queries.push(db.insert(Comment).values({ body: `Test comment ${i}` }));
}
await db.batch(queries);
}

Voir la documentation Drizzle db.batch() pour plus de détails.

Fonctionnalité Studio

Astro DB peut se connecter à la plateforme Astro Studio pour ajouter rapidement une base de données hébergée à votre projet. Vous pouvez visualiser, gérer et déployer de nouvelles bases de données hébergées à partir du portail web Astro Studio.

Le portail web Astro Studio vous permet de vous connecter et de gérer vos bases de données Astro DB hébergées à distance via une interface web ou en utilisant des commandes CLI.

Depuis votre tableau de bord Studio, vous avez accès à la gestion de votre compte, à des articles d’aide et à une console de messages d’assistance.

Visitez Astro Studio pour vous inscrire ou vous connecter.

Fonctionnalité Studio

Il existe deux façons de créer un projet dans Astro Studio :

  1. Utiliser l’interface web Astro Studio pour créer à partir d’un dépôt GitHub nouveau ou existant.

Pour commencer, cliquez sur le bouton “créer un projet” dans l’en-tête et suivez les instructions. Astro Studio se connectera à votre dépôt GitHub et créera une nouvelle base de données hébergée pour votre projet.

  1. Utilisez le CLI d’Astro Studio pour créer à partir de n’importe quel projet Astro local. Vous pouvez exécuter les commandes suivantes pour commencer :
Fenêtre de terminal
# Connectez-vous à Astro Studio avec votre compte GitHub
npx astro login
# Créez un lien vers un nouveau projet en suivant les instructions.
npx astro link
# (Facultatif) Transférer la configuration de la base de données locale vers la base de données distante.
npx astro db push

Une fois connecté et relié avec succès, vous pouvez exécuter toutes les commandes Astro DB pour gérer votre base de données distante.

Voir la référence CLI Astro DB pour toutes les commandes disponibles.
Fonctionnalité Studio

Vous pouvez déployer votre projet Astro DB avec une connexion en direct à votre base de données Studio. Ceci est possible avec n’importe quelle plateforme de déploiement utilisant des constructions statiques ou un adaptateur SSR.

Tout d’abord, configurez votre commande de compilation pour qu’elle se connecte à Studio en utilisant l’option --remote. Cet exemple applique le drapeau à un script "build" dans le package.json de votre projet. Si votre plateforme de déploiement accepte une commande de construction, assurez-vous qu’elle est définie comme npm run build.

package.json
{
"scripts": {
"build": "astro build --remote"
}
}
Fonctionnalité Studio

Vous devez créer un jeton d’application pour accéder à votre base de données Studio à partir d’un déploiement en production. Vous pouvez créer un jeton d’application à partir du tableau de bord de votre projet Studio en accédant à l’onglet Settings et en sélectionnant Tokens.

Copiez le jeton généré et appliquez-le en tant que variable d’environnement / secret d’environnement dans votre plateforme de déploiement en utilisant le nom ASTRO_STUDIO_APP_TOKEN.

Fonctionnalité Studio

Vous pouvez pousser automatiquement les changements de schéma dans votre base de données Studio avec l’action Studio CI. Cela permet de vérifier que les changements peuvent être effectués en toute sécurité, et de maintenir votre configuration à jour à chaque fois que vous fusionnez avec main.

Suivez la documentation de GitHub pour configurer un nouveau secret dans votre dépôt avec le nom ASTRO_STUDIO_APP_TOKEN et le jeton de votre application Studio comme valeur pour le secret.

Une fois que votre secret est configuré, créez un nouveau fichier de workflow GitHub Actions dans le répertoire .github/workflows de votre projet pour extraire le dépôt et installer Node.js comme étape, et utilisez l’action withastro/action-studio pour synchroniser les changements de schémas.

L’action lancera astro db verify sur tous les déclencheurs d`évènements pour s’assurer que les changements de schéma peuvent être appliqués en toute sécurité. Si vous ajoutez spécifiquement le déclencheur push, l’action poussera ces changements dans la base de données de Studio.

Cet exemple d’action GitHub _studio.yml pousse les changements à chaque fois que la branche main est mise à jour :

.github/workflows/_studio.yml
name: Astro Studio
env:
ASTRO_STUDIO_APP_TOKEN: ${{secrets.ASTRO_STUDIO_APP_TOKEN }}
on:
push:
branches:
- main
pull_request:
types: [opened, reopened, synchronize]
jobs:
DB:
permissions:
contents: read
actions: read
pull-requests: write
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- uses: jaid/action-npm-install@v1.2.1
- uses: withastro/action-studio@main
Fonctionnalité Studio

Le schéma de vos tables évoluera au fur et à mesure que votre projet se développera. Vous pouvez tester en toute sécurité les changements de configuration localement et les transférer dans la base de données de Studio lors du déploiement.

Lorsque vous créez un projet Studio à partir du tableau de bord, vous avez la possibilité de créer une action GitHub CI. Cette action migrera automatiquement les changements de schéma lors de la fusion avec la branche principale de votre dépôt.

Vous pouvez aussi pousser les changements de schéma via le CLI en utilisant la commande astro db push --remote :

Fenêtre de terminal
npm run astro db push --remote

Cette commande vérifiera que les changements peuvent être effectués sans perte de données et guidera sur les changements de schéma recommandés pour résoudre les conflits. Si une modification du schéma doit être faite, ajoutez le drapeau --force-reset pour réinitialiser toutes les données de production.

Pousser les changements majeurs de schéma

Titre de la section Pousser les changements majeurs de schéma

Si vous devez modifier le schéma de votre table d’une manière incompatible avec vos données existantes hébergées chez Astro Studio, vous devrez réinitialiser votre base de données de production.

Pour pousser une mise à jour du schéma de table qui inclut un changement radical, ajoutez le drapeau --force-reset pour réinitialiser toutes les données de production :

Fenêtre de terminal
npm run astro db push --remote --force-reset
Fonctionnalité Studio

Il est possible de renommer une table après avoir transféré votre schéma dans Astro Studio.

Si vous n’avez pas de données de production importantes, alors vous pouvez réinitialiser votre base de données en utilisant l’option --force-reset. Ce drapeau supprimera toutes les tables de la base de données et en créera de nouvelles afin qu’elle corresponde exactement à votre schéma actuel.

Pour renommer une table tout en préservant vos données de production, vous devez effectuer une série de modifications irréversibles afin de transférer votre schéma local vers Astro studio en toute sécurité.

L’exemple suivant renomme une table de Comment en Feedback :

  1. Dans le fichier de configuration de votre base de données, ajoutez la propriété deprecated : true à la table que vous voulez renommer :

    db/config.ts
    const Comment = defineTable({
    deprecated: true,
    columns: {
    author: column.text(),
    body: column.text(),
    }
    });
  2. Ajoutez un nouveau schéma de table (correspondant exactement aux propriétés de la table existante) avec le nouveau nom :

    db/config.ts
    const Comment = defineTable({
    deprecated: true,
    columns: {
    author: column.text(),
    body: column.text(),
    }
    });
    const Feedback = defineTable({
    columns: {
    author: column.text(),
    body: column.text(),
    }
    });
  3. Poussez vers Astro Studio avec astro db push --remote. Cela ajoutera la nouvelle table et marquera l’ancienne comme obsolète.

  4. Mettez à jour le code de votre projet local pour utiliser la nouvelle table au lieu de l’ancienne. Il se peut que vous deviez également migrer des données vers la nouvelle table.

  5. Une fois que vous êtes sûr que l’ancienne table n’est plus utilisée dans votre projet, vous pouvez supprimer le schéma de votre config.ts :

    db/config.ts
    const Comment = defineTable({
    deprecated: true,
    columns: {
    author: column.text(),
    body: column.text(),
    }
    });
    const Feedback = defineTable({
    columns: {
    author: column.text(),
    body: column.text(),
    }
    });
  6. Poussez à nouveau vers Astro Studio avec astro db push --remote. L’ancienne table sera supprimée, ne laissant que la nouvelle table renommée.

Fonctionnalité Studio

Vous pouvez avoir besoin de pousser des données vers votre base de données Studio pour les seed (données initiales) ou les migrations de données. Vous pouvez créer un fichier .ts avec le module astro:db pour écrire des requêtes sûres. Ensuite, exécutez le fichier contre votre base de données Studio en utilisant la commande astro db execute <file-path> --remote :

Les commentaires suivants peuvent être initiés à l’aide de la commande astro db execute db/seed.ts --remote :

db/seed.ts
import { Comment } from 'astro:db';
export default async function () {
await db.insert(Comment).values([
{ authorId: 1, body: "J'espère que vous aimerez Astro DB !" },
{ authorId: 2, body: 'Profitez !' },
])
}

Voir la référence CLI pour une liste complète des commandes.

Fonctionnalité Studio

Par défaut, Astro utilisera un fichier de base de données local chaque fois que vous lancerez les commandes dev ou build. Les tables sont recréées à partir de zéro lors de l’exécution de chaque commande, et les données d’amorçage du développement seront insérées.

Pour vous connecter à votre base de données Studio hébergée, vous pouvez ajouter l’option --remote. Utilisez ce drapeau pour les déploiements en production afin d’avoir un accès en lecture et en écriture à votre base de données Studio. Cela vous permettra d’accepter et de persister les données des utilisateurs.

Fenêtre de terminal
# Construire avec une connexion à distance
astro build --remote
# Développer avec une connexion à distance
astro dev --remote

Pour utiliser une connexion à distance, vous aurez besoin d’un jeton d’application pour vous authentifier auprès de Studio. Consultez le tableau de bord de Studio pour obtenir des instructions sur la création et la configuration d’un jeton.

Lorsque vous êtes prêt à déployer, consultez notre guide Déployer avec une connexion Studio.

Les intégrations Astro permettent d’étendre les projets des utilisateurs avec des tables Astro DB supplémentaires et des données de départ.

Utilisez la méthode extendDb() dans le hook astro:db:setup pour enregistrer des fichiers de configuration et de la données initiales (seed) Astro DB supplémentaires. L’aide defineDbIntegration() fournit le support TypeScript et l’auto-complétion pour le crochet astro:db:setup.

my-integration/index.ts
import { defineDbIntegration } from '@astrojs/db/utils';
export default function MyIntegration() {
return defineDbIntegration({
name: 'my-astro-db-powered-integration',
hooks: {
'astro:db:setup': ({ extendDb }) => {
extendDb({
configEntrypoint: '@astronaut/my-package/config',
seedEntrypoint: '@astronaut/my-package/seed',
});
},
// Autres fonctions d'intégration...
},
});
}

Les fichiers d’intégration config et seed suivent le même format que leurs équivalents définis par l’utilisateur.

Opérations de sécurité dans les intégrations

Titre de la section Opérations de sécurité dans les intégrations

Lorsque vous travaillez sur des intégrations, il se peut que vous ne puissiez pas bénéficier des types de table générés par Astro et exportés depuis astro:db. Pour une sécurité totale des types, utilisez l’utilitaire asDrizzleTable() pour créer un objet de référence de table que vous pouvez utiliser pour les opérations de base de données.

Par exemple, dans le cas d’une intégration mettant en place la table de base de données Pets suivante :

my-integration/config.ts
import { defineDb, defineTable, column } from 'astro:db';
export const Pets = defineTable({
columns: {
name: column.text(),
species: column.text(),
},
});
export default defineDb({ tables: { Pets } });

Le fichier seed (données initiales) peut importer Pets et utiliser asDrizzleTable() pour insérer des lignes dans votre table avec vérification du type :

my-integration/seed.ts
import { asDrizzleTable } from '@astrojs/db/utils';
import { db } from 'astro:db';
import { Pets } from './config';
export default async function() {
const typeSafePets = asDrizzleTable('Pets', Pets);
await db.insert(typeSafePets).values([
{ name: 'Palomita', species: 'cat' },
{ name: 'Pan', species: 'dog' },
]);
}

La valeur retournée par asDrizzleTable('Pets', Pets) est équivalente à import { Pets } from 'astro:db', mais elle est disponible même si la génération de type d’Astro ne peut pas fonctionner. Vous pouvez l’utiliser dans tout code d’intégration qui doit interroger ou insérer dans la base de données.

Déploiement de la production en auto-hébergement

Titre de la section Déploiement de la production en auto-hébergement

Si vous déployez votre site sur un hôte autogéré tel qu’un serveur privé virtuel, vous pouvez choisir d’utiliser un fichier de base de données au lieu de vous connecter à une base de données hébergée chez Astro Studio.

Si vous êtes prêt à prendre des risques et que vous pouvez gérer le déploiement vous-même, vous pouvez utiliser un fichier de base de données au lieu de vous connecter à Studio.

Définissez la variable d’environnement ASTRO_DATABASE_FILE avec un chemin pointant vers votre fichier .db dans l’environnement de l’hôte pendant votre compilation :

Fenêtre de terminal
ASTRO_DATABASE_FILE=/srv/files/database.db astro build

La compilation se fera de manière statique avec ce chemin comme base de données de production. Lorsque vous déployez et lancez votre serveur, il se connectera au fichier à ce chemin sur l’hôte de production.

En outre, pousser tout changement de schéma de table (également connu sous le nom de “migrations de schéma”) doit être géré manuellement à l’aide de cette variable d’environnement.