NOUVEAU 📢 Offre de lancement limitée : jusqu'à 70 % de remise sur votre premier mois, pour tous les jeux !Voir les offres

Utiliser Prisma avec MySQL dans un bot Discord

Hébergement de bots DiscordUpdated Nov 6, 202610 min read

Réponse courte. Utilisez Prisma 7 avec l'adaptateur de pilote @prisma/adapter-mariadb, que Prisma documente pour MySQL et MariaDB. Chez PlayNHost, prisma migrate dev ne peut pas s'exécuter sur la base de données de votre bot, car il doit créer une base « shadow » temporaire et les utilisateurs de base de données ne peuvent pas créer de bases ici. Écrivez plutôt la première migration avec prisma migrate diff, qui n'a besoin d'aucune base, et laissez un script postinstall lancer prisma generate et prisma migrate deploy sur le serveur. Chaque offre de bot comprend une base de données MySQL. Nous avons testé le code et les commandes ci-dessous le 6 novembre 2026 avec Prisma 7.10.1, discord.js 14 et Node.js 22, sur MariaDB 10.11 avec un compte de base de données configuré comme le nôtre (pas de droit de créer des bases, 20 connexions, limite de requête de 120 secondes), mais pas avec une vraie connexion à Discord.

Prisma 7, pas la dernière version npm

Le 6 novembre 2026, le tag latest du paquet prisma sur npm pointe vers une release candidate de Prisma 8 (8.0.0-rc.30), et le quickstart MySQL de Prisma est celui de Prisma 7 : il installe prisma@prev et @prisma/client@7. Ce guide fixe donc tous les paquets Prisma sur ^7. Un simple npm install prisma vous donnerait la version 8.

Ce qu'il vous faut

  • Un bot discord.js Ă©crit en TypeScript. Notre type Node.js Bot exĂ©cute avec tsx un fichier principal se terminant par .ts, donc rien n'a besoin d'ĂŞtre compilĂ© avant : Comment faire tourner un bot Discord TypeScript.
  • Une offre de bot PlayNHost avec le type Node.js Bot. Chaque offre comprend une base de donnĂ©es.
  • Node.js et npm sur votre propre ordinateur, pour Ă©crire la migration une fois.

1. Créer la base de données et les variables

  1. Ouvrez le serveur de votre bot dans le panel, cliquez sur Bases de données, puis sur Nouvelle base de données et Créer une base de données.
  2. La page de la nouvelle base s'ouvre (plus tard, cliquez dessus dans Vos bases de données). Gardez-la ouverte et, sous Config prête à l’emploi, choisissez Generic URL dans Config pour : c'est la chaîne de connexion mysql://... dont la ligne de commande Prisma a besoin.
  3. Ouvrez la page Bot, le volet Environnement, cliquez sur Coller un fichier .env et collez six lignes avec vos valeurs. Pour DATABASE_URL, collez la Generic URL exactement telle qu'affichée : les mots de passe de nos bases peuvent contenir des caractères comme @ et +, que Prisma exige encodés en pourcentage dans une URL, et la Generic URL est déjà encodée.
    DB_HOST=your-host
    DB_PORT=3306
    DB_NAME=your-database
    DB_USER=your-username
    DB_PASSWORD=your-password
    DATABASE_URL=mysql://your-username:your-password@your-host:3306/your-database
  4. DB_PASSWORD et DATABASE_URL reçoivent un badge Secret : ils sont enregistrés en écriture seule. Cliquez sur Importer 6 variables.

Le bot lui-même se connecte avec les cinq valeurs DB_, transmises une par une à l'adaptateur comme dans le quickstart de Prisma. DATABASE_URL ne sert qu'aux commandes prisma exécutées pendant l'installation.

2. Les fichiers du projet

package.json

{
  "name": "my-discord-bot",
  "private": true,
  "type": "module",
  "scripts": {
    "postinstall": "prisma generate && prisma migrate deploy"
  },
  "dependencies": {
    "@prisma/adapter-mariadb": "^7",
    "@prisma/client": "^7",
    "discord.js": "^14"
  },
  "devDependencies": {
    "prisma": "^7"
  }
}

prisma7.config.ts (Prisma 7.10 et les versions suivantes utilisent ce nom, pour ne pas entrer en conflit avec le prisma.config.ts de Prisma 8)

import { defineConfig } from "prisma/config";

export default defineConfig({
  schema: "prisma/schema.prisma",
  migrations: {
    path: "prisma/migrations",
  },
  datasource: {
    url: process.env.DATABASE_URL,
  },
});

prisma/schema.prisma

generator client {
  provider = "prisma-client"
  output   = "../generated/prisma"
}

datasource db {
  provider = "mysql"
}

model Warning {
  id        Int      @id @default(autoincrement())
  guildId   String   @db.VarChar(20)
  userId    String   @db.VarChar(20)
  reason    String   @db.VarChar(200)
  createdAt DateTime @default(now())

  @@index([guildId, userId])
}

index.ts

import { Client, Events, GatewayIntentBits, InteractionContextType, MessageFlags, REST, Routes, SlashCommandBuilder } from "discord.js";
import { PrismaMariaDb } from "@prisma/adapter-mariadb";
import { PrismaClient } from "./generated/prisma/client";

// One client for the whole bot. The values come from the Environment pane.
const adapter = new PrismaMariaDb({
  host: process.env.DB_HOST,
  port: Number(process.env.DB_PORT),
  user: process.env.DB_USER,
  password: process.env.DB_PASSWORD,
  database: process.env.DB_NAME,
  connectionLimit: 5,
});
const prisma = new PrismaClient({ adapter });

const commands = [
  new SlashCommandBuilder()
    .setName("warn")
    .setDescription("Warn a member and count their warnings")
    .setContexts(InteractionContextType.Guild)
    .addUserOption((o) => o.setName("user").setDescription("Who to warn").setRequired(true))
    .addStringOption((o) => o.setName("reason").setDescription("Why").setRequired(true).setMaxLength(200))
    .toJSON(),
];

const client = new Client({ intents: [GatewayIntentBits.Guilds] });

client.once(Events.ClientReady, async (c) => {
  await new REST().setToken(process.env.DISCORD_TOKEN!).put(Routes.applicationCommands(c.user.id), { body: commands });
  console.log(`Logged in as ${c.user.tag}`);
});

client.on(Events.InteractionCreate, async (interaction) => {
  if (!interaction.isChatInputCommand() || interaction.commandName !== "warn" || !interaction.guildId) return;
  const user = interaction.options.getUser("user", true);
  const reason = interaction.options.getString("reason", true);
  try {
    await prisma.warning.create({ data: { guildId: interaction.guildId, userId: user.id, reason } });
    const total = await prisma.warning.count({ where: { guildId: interaction.guildId, userId: user.id } });
    await interaction.reply(`${user} has ${total} warning(s).`);
  } catch (err) {
    console.error(err);
    if (!interaction.replied) await interaction.reply({ content: "Could not save the warning. Try again later.", flags: MessageFlags.Ephemeral }).catch(console.error);
  }
});

client.login(process.env.DISCORD_TOKEN);

setContexts(InteractionContextType.Guild) et la vérification !interaction.guildId empêchent /warn de fonctionner en message privé. Le try/catch est important : sans lui, discord.js transmet une requête échouée à son événement error, et quand personne n'y écoute, Node.js arrête le bot.

3. Écrire la première migration sur votre ordinateur

Dans le dossier du projet sur votre propre ordinateur (sous Windows, créez à la main les dossiers prisma\migrations\0_init au lieu d'utiliser mkdir -p) :

npm install --ignore-scripts
mkdir -p prisma/migrations/0_init
npx prisma migrate diff --from-empty --to-schema prisma/schema.prisma --script > prisma/migrations/0_init/migration.sql

migrate diff compare une base vide avec votre schéma et écrit le SQL, sans se connecter à aucune base de données. --ignore-scripts ignore le postinstall, qui essaierait de joindre une base. Le fichier commence par -- CreateTable et CREATE TABLE `Warning`.

4. Téléverser et démarrer

  1. Dans Fichiers, téléversez package.json, prisma7.config.ts, index.ts et le dossier prisma avec schema.prisma et migrations. Ne téléversez pas node_modules ni generated : le serveur construit les deux.
  2. Sur la page Bot, volet Code, réglez Fichier d’entrée sur index.ts.
  3. Appuyez sur Démarrer et ouvrez Console. L'installation exécute votre postinstall : vous voyez Generated Prisma Client (7.10.1), puis All migrations have been successfully applied., puis [PlayNHost] Starting your bot et Logged in as ....

La console affiche aussi npm warn install-scripts 2 packages had install scripts blocked pour prisma et @prisma/engines. La version de npm de notre image Node.js 22 bloque les scripts d'installation des dépendances tant qu'ils ne sont pas autorisés. Votre propre postinstall s'exécute quand même, et dans notre test Prisma a généré, migré et interrogé sans ces scripts.

Pourquoi pas prisma migrate dev ?

prisma migrate dev crée d'abord une base shadow temporaire pour vérifier vos migrations. L'utilisateur de la base de votre bot peut travailler dans sa propre base mais ne peut pas en créer de nouvelles, donc sur nos serveurs la commande s'arrête avec :

Prisma Migrate could not create the shadow database. Please make sure the database user has permission to create databases. Read more about the shadow database (and workarounds) at https://pris.ly/d/migrate-shadow

Original error: Error code: P1010

User was denied access on the database `prisma_migrate_shadow_db_...`

prisma migrate deploy applique seulement les fichiers de migration et n'a pas besoin de base shadow, c'est pourquoi le postinstall l'utilise. Vous ne pouvez pas non plus pointer migrate dev vers la base du bot depuis votre propre ordinateur : la base n'accepte que les connexions des serveurs PlayNHost et de phpMyAdmin.

Modifier le schéma plus tard

  1. Sur votre ordinateur, lancez npx prisma migrate dev --name suivi d'un nom pour la modification, sur un MySQL ou MariaDB à vous, par exemple dans Docker : définissez DATABASE_URL dans votre terminal sur cette base, car prisma7.config.ts la lit dans l'environnement. Cela écrit un nouveau dossier dans prisma/migrations.
  2. Téléversez le nouveau dossier de migration et le schema.prisma modifié.
  3. Le serveur exécute npm install, et avec lui votre postinstall, seulement quand package.json, package-lock.json ou la version de Node.js ont changé, quand node_modules est absent, ou au premier démarrage plus d'un jour après la dernière installation. Pour appliquer la migration tout de suite, modifiez package.json (par exemple son version) ou supprimez le dossier node_modules dans Fichiers, puis redémarrez.

Mémoire : l'installation est la partie lourde

Nous avons installé ce projet de zéro dans un conteneur plafonné à 512 Mo, comme notre plus petite offre de bot. L'installation, avec prisma generate et prisma migrate deploy, a pris 41 secondes et a atteint un pic de 386 Mo de mémoire (cache de fichiers non compté) lors d'une exécution et de 417 Mo lors d'une seconde, sans arrêt pour manque de mémoire dans aucune des deux. Elle tient dans l'offre de 512 Mo avec moins de 100 Mo de marge, donc un projet plus gros ou plus de paquets pourraient dépasser. La même installation sans Prisma (discord.js et mysql2 seulement) a atteint un pic de 147 Mo.

Limites et erreurs

  • 20 connexions simultanĂ©es par utilisateur de base de donnĂ©es, tous les processus utilisant le mĂŞme identifiant confondus. Gardez connectionLimit bas ; 5 suffisent largement pour un bot.
  • Une requĂŞte qui dure plus de 120 secondes est arrĂŞtĂ©e, avec l'erreur 1969 Query execution was interrupted (max_statement_time exceeded).
  • 500 Mo par base de donnĂ©es : Ă  500 Mo, les Ă©critures sont bloquĂ©es jusqu'Ă  ce que vous supprimiez des lignes. Les sauvegardes du serveur n'incluent pas la base de donnĂ©es. Exportez-la de temps en temps depuis phpMyAdmin.
  • Les problèmes de connexion ont les mĂŞmes causes qu'avec mysql2 (mauvais mot de passe, mauvais hĂ´te ou port, une variable absente dans Environnement, connexion depuis votre propre ordinateur), mais les messages sont diffĂ©rents : l'adaptateur MariaDB utilise le pilote mariadb, pas mysql2, et nous n'avons pas relevĂ© ses messages. Les causes sont listĂ©es dans Comment utiliser une base de donnĂ©es MySQL avec un bot discord.js.

Du SQL simple avec mysql2 ou aiomysql à la place : discord.js (mysql2), discord.py (aiomysql). Le panorama : Comment utiliser une base de données avec votre bot Discord. Besoin d'un serveur de bot avec base de données incluse ? Voir les offres de bot.

Votre bot est hébergé ailleurs ? Transférez-le chez nous

NOS DERNIERS ARTICLES