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

Comment utiliser une base de données MySQL avec un bot discord.py (aiomysql)

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

Réponse courte. Ajoutez aiomysql à votre bot discord.py, créez un seul pool dans setup_hook avec autocommit=True, et faites passer chaque requête par lui avec des marqueurs %s. Sans autocommit=True (ou un commit() après chaque écriture), aiomysql n’enregistre pas vos INSERT. Chez PlayNHost, chaque offre de bot inclut une base de données MySQL : créez-la sur la page Bases de données, collez ses informations dans le volet Environnement, et le code ci-dessous fonctionne tel quel. La base de données accepte les connexions de vos serveurs PlayNHost et de phpMyAdmin, pas celles de votre propre ordinateur. Nous avons testé ce code le 6 novembre 2026 avec discord.py 2.7.1, aiomysql 0.3.2 et Python 3.12, sur MariaDB 10.11 avec un compte de base de données configuré comme le nôtre (20 connexions, limite de requête de 120 secondes) : le démarrage, la table et la commande /warn, mais pas une vraie connexion à Discord.

Ce qu’il vous faut

1. Créer la base de données

  1. Ouvrez votre serveur de bot dans le panel et cliquez sur Bases de données.
  2. Cliquez sur Nouvelle base de données. Le Libellé est facultatif ; Sera créée sous le nom affiche le nom complet. Cliquez sur Créer une base de données.
  3. La page de la nouvelle base s’ouvre (plus tard, cliquez dessus dans Vos bases de données). Sa carte Connexion affiche Hôte, Port, Base de données, Nom d’utilisateur et Mot de passe. Sous Config prête à l’emploi, Config pour propose un extrait Python (aiomysql) avec les mêmes valeurs déjà remplies.

2. Enregistrer les identifiants dans Environnement

  1. Ouvrez la page Bot, le volet Environnement, et cliquez sur Coller un fichier .env.
  2. Collez ces cinq lignes avec les valeurs de la carte Connexion :
    DB_HOST=your-host
    DB_PORT=3306
    DB_NAME=your-database
    DB_USER=your-username
    DB_PASSWORD=your-password
  3. DB_PASSWORD reçoit un badge Secret : il est enregistré en écriture seule et n’est plus jamais affiché. Cliquez sur Importer 5 variables.

Utilisez le vrai port de la carte Connexion. Votre code lit les valeurs avec os.environ, donc le mot de passe ne se trouve jamais dans les fichiers de votre bot. Plus de détails sur ce volet : Comment définir des variables d’environnement et des secrets pour votre bot Discord.

3. Le code

requirements.txt

discord.py
aiomysql

bot.py

import os

import aiomysql
import discord
from discord import app_commands


class Bot(discord.Client):
    def __init__(self):
        super().__init__(intents=discord.Intents.default())
        self.tree = app_commands.CommandTree(self)
        self.pool = None

    async def setup_hook(self):
        # One pool for the whole bot. The values come from the Environment pane.
        self.pool = await aiomysql.create_pool(
            host=os.environ["DB_HOST"],
            port=int(os.environ["DB_PORT"]),
            user=os.environ["DB_USER"],
            password=os.environ["DB_PASSWORD"],
            db=os.environ["DB_NAME"],
            autocommit=True,
            maxsize=5,
        )
        async with self.pool.acquire() as conn:
            async with conn.cursor() as cur:
                await cur.execute(
                    "CREATE TABLE IF NOT EXISTS warnings ("
                    "id INT AUTO_INCREMENT PRIMARY KEY, "
                    "guild_id BIGINT UNSIGNED NOT NULL, "
                    "user_id BIGINT UNSIGNED NOT NULL, "
                    "reason VARCHAR(200) NOT NULL, "
                    "created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, "
                    "KEY guild_user (guild_id, user_id))"
                )
        print("Database ready")
        await self.tree.sync()

    async def close(self):
        if self.pool is not None:
            self.pool.close()
            await self.pool.wait_closed()
        await super().close()


bot = Bot()


@bot.tree.command(description="Warn a member and count their warnings")
@app_commands.guild_only()
@app_commands.describe(user="Who to warn", reason="Why")
async def warn(interaction: discord.Interaction, user: discord.Member, reason: app_commands.Range[str, 1, 200]):
    async with bot.pool.acquire() as conn:
        async with conn.cursor() as cur:
            await cur.execute(
                "INSERT INTO warnings (guild_id, user_id, reason) VALUES (%s, %s, %s)",
                (interaction.guild_id, user.id, reason),
            )
            await cur.execute(
                "SELECT COUNT(*) FROM warnings WHERE guild_id = %s AND user_id = %s",
                (interaction.guild_id, user.id),
            )
            (total,) = await cur.fetchone()
    await interaction.response.send_message(f"{user.mention} has {total} warning(s).")


@bot.event
async def on_ready():
    print(f"Logged in as {bot.user}")


bot.run(os.environ["DISCORD_TOKEN"])

Ce qu’il fait : discord.py exécute setup_hook une seule fois, pendant la connexion et avant l’arrivée de tout événement, si bien que le pool et la table warnings existent avant l’arrivée de la première commande. Il enregistre ensuite /warn auprès de Discord. @app_commands.guild_only() tient la commande à l’écart des messages privés, où il n’y a aucun serveur pour enregistrer l’avertissement. Les ID Discord tiennent dans BIGINT UNSIGNED. Les marqueurs %s sont remplis par le pilote, si bien qu’un motif comme '); DROP TABLE warnings; -- est enregistré comme du texte brut. Ne construisez jamais le SQL avec une f-string.

4. Lancer le bot

  1. Envoyez bot.py et requirements.txt dans Fichiers.
  2. Appuyez sur Démarrer et ouvrez Console. Le démarrage installe les paquets de requirements.txt, puis affiche [PlayNHost] Starting your bot et Database ready.
  3. Dans Discord, tapez /warn. Pour voir les lignes, ouvrez la page de la base et cliquez sur Ouvrir dans phpMyAdmin.

Le piège de l’autocommit

aiomysql ouvre les connexions avec l’autocommit désactivé. Un INSERT reste alors dans une transaction ouverte. Quand la connexion retourne dans le pool avec cette transaction encore ouverte, aiomysql la ferme, et MariaDB jette la ligne non validée. Dans notre test, une ligne insérée sur un pool sans autocommit=True a été vue par 0 autre connexion. Passez autocommit=True à create_pool, comme ci-dessus, ou appelez await conn.commit() après vos écritures.

Les limites qui comptent pour votre pool

  • 20 connexions simultanées par utilisateur de base de données. Tout processus qui utilise le même identifiant compte. La connexion 21 est refusée avec (1226, "User '...' has exceeded the 'max_user_connections' resource (current value: 20)"). maxsize=5 garde le bot bien en dessous.
  • Une requête qui dure plus de 120 secondes est interrompue. MariaDB y met fin avec l’erreur 1969, Query execution was interrupted (max_statement_time exceeded). Dans notre test, cela est arrivé après 120.03 secondes. Les requêtes d’un bot prennent normalement des millisecondes, donc cela ne touche qu’une requête qui s’emballe.
  • 500 MB par base de données. La page Bases de données indique l’espace utilisé. À 500 MB, 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 erreurs et leur signification

Voici les erreurs exactes qu’aiomysql a données dans notre test (elles viennent de PyMySQL, qu’aiomysql utilise en dessous) :

  • pymysql.err.OperationalError (1045, "Access denied for user ...") : DB_USER ou DB_PASSWORD incorrect. Après Réinitialiser le mot de passe sur la carte Connexion, l’ancien mot de passe cesse de fonctionner immédiatement : remplacez DB_PASSWORD et redémarrez le bot.
  • pymysql.err.OperationalError (2003, "Can't connect to MySQL server on ...") : hôte ou port incorrect, ou connexion depuis l’extérieur de PlayNHost. La base de données n’accepte que les connexions des serveurs PlayNHost et de phpMyAdmin, c’est donc aussi ce que vous obtenez depuis votre propre ordinateur.
  • (1226, ... 'max_user_connections' ...) : trop de connexions ouvertes, voir les limites ci-dessus.

Une variable absente de Environnement arrête le bot avant sa connexion, avec KeyError: 'DB_HOST' ou le nom de celle qui manque, car le code lit chaque valeur avec os.environ[...]. Ajoutez-la, puis redémarrez le bot : les variables s’appliquent au prochain démarrage.

Plus d’erreurs de bot : Erreurs courantes des bots Discord et leur signification.

Combien de mémoire cela ajoute

Installer discord.py et aiomysql avec pip de zéro a atteint un pic de 78 MB de mémoire dans notre test, dans un conteneur limité à 512 MB comme notre plus petite offre de bot. La mémoire dont le bot en marche a besoin dépend surtout du nombre de serveurs où il se trouve : De combien de RAM un bot Discord a-t-il besoin ?

La même chose en JavaScript, ou avec Prisma

Besoin d’un serveur de bot avec une base de données incluse ? Voir les offres de bots.

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

NOS DERNIERS ARTICLES