Risposta breve. Aggiungi aiomysql al tuo bot discord.py, crea un solo pool in setup_hook con autocommit=True ed esegui ogni query attraverso di esso con segnaposto %s. Senza autocommit=True (o un commit() dopo ogni scrittura), aiomysql non salva i tuoi INSERT. Su PlayNHost ogni piano per bot include un database MySQL: crealo nella pagina Database, incolla i suoi dati nel riquadro Ambiente e il codice qui sotto funziona così com'è. Il database accetta connessioni dai tuoi server PlayNHost e da phpMyAdmin, non dal tuo computer. Abbiamo testato questo codice il 6 novembre 2026 con discord.py 2.7.1, aiomysql 0.3.2 e Python 3.12, su MariaDB 10.11 con un account database configurato come il nostro (20 connessioni, limite di 120 secondi per query): l'avvio, la tabella e il comando /warn, ma non un vero login su Discord.
Apri il tuo server bot nel pannello e clicca su Database.
Clicca su Nuovo database. Un'Etichetta è facoltativa; Verrà creato come mostra il nome completo. Clicca su Crea database.
Si apre la pagina del nuovo database (più avanti, cliccalo in I tuoi database). La sua scheda Connessione mostra Host, Porta, Database, Nome utente e Password. Sotto Config pronta all’uso, Config per contiene uno snippet Python (aiomysql) con gli stessi valori già compilati.
2. Metti i dati in Ambiente
Apri la pagina Bot, il riquadro Ambiente, e clicca su Incolla un file .env.
Incolla queste cinque righe con i valori della scheda Connessione:
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"])
Cosa fa: discord.py esegue setup_hook una sola volta, durante il login e prima che arrivi qualsiasi evento, quindi il pool e la tabella warnings esistono prima che arrivi il primo comando. Poi registra /warn su Discord. @app_commands.guild_only() tiene il comando fuori dai messaggi privati, dove non c'è nessun server a cui associare l'avvertimento. Gli ID Discord stanno in BIGINT UNSIGNED. I segnaposto %s vengono riempiti dal driver, quindi un motivo come '); DROP TABLE warnings; -- viene salvato come semplice testo. Non costruire mai l'SQL con una f-string.
4. Avvialo
Carica bot.py e requirements.txt in Files.
Premi Avvia e apri Console. All'avvio vengono installati i pacchetti da requirements.txt, poi compaiono [PlayNHost] Starting your bot e Database ready.
Su Discord, scrivi /warn. Per vedere le righe, apri la pagina del database e clicca su Apri in phpMyAdmin.
La trappola dell'autocommit
aiomysql apre le connessioni con l'autocommit disattivato. Un INSERT resta allora dentro una transazione aperta. Quando la connessione torna nel pool con quella transazione ancora aperta, aiomysql la chiude e MariaDB scarta la riga non confermata. Nel nostro test, una riga inserita su un pool senza autocommit=True è stata vista da 0 altre connessioni. Passa autocommit=True a create_pool, come sopra, oppure chiama await conn.commit() dopo le tue scritture.
I limiti che contano per il tuo pool
20 connessioni contemporanee per utente del database. Conta ogni processo che usa lo stesso accesso. La connessione 21 viene rifiutata con (1226, "User '...' has exceeded the 'max_user_connections' resource (current value: 20)"). maxsize=5 tiene il bot ben al di sotto.
Una query che dura più di 120 secondi viene interrotta. MariaDB la termina con l'errore 1969, Query execution was interrupted (max_statement_time exceeded). Nel nostro test è successo dopo 120.03 secondi. Le query di un bot di solito durano millisecondi, quindi questo riguarda solo una query fuori controllo.
I backup del server non includono il database. Esportalo da phpMyAdmin ogni tanto.
Errori e cosa significano
Questi sono gli errori esatti che aiomysql ha dato nel nostro test (arrivano da PyMySQL, che aiomysql usa sotto il cofano):
pymysql.err.OperationalError (1045, "Access denied for user ..."): DB_USER o DB_PASSWORD errati. Dopo Reimposta password nella scheda Connessione, la vecchia password smette di funzionare subito: sostituisci DB_PASSWORD e riavvia il bot.
pymysql.err.OperationalError (2003, "Can't connect to MySQL server on ..."): host o porta errati, oppure una connessione dall'esterno di PlayNHost. Il database accetta solo connessioni dai server PlayNHost e da phpMyAdmin, quindi è anche ciò che ottieni dal tuo computer.
(1226, ... 'max_user_connections' ...): troppe connessioni aperte, vedi i limiti qui sopra.
Installare discord.py e aiomysql con pip da zero ha toccato un picco di 78 MB di memoria nel nostro test, in un container limitato a 512 MB come il nostro piano bot più piccolo. Quanta ne serve al bot in esecuzione dipende soprattutto da in quanti server si trova: Di quanta RAM ha bisogno un bot Discord?
Utilizziamo i cookie per far funzionare il sito, capire come viene usato e misurare il nostro marketing. Puoi accettare tutto, accettare solo i cookie essenziali o scegliere per categoria.Utilizziamo i cookie per far funzionare il sito, capire come viene usato e misurare il nostro marketing. Qui sono attivi per impostazione predefinita: puoi disattivare ciò che non desideri.Leggi la nostra informativa sulla privacy