如何在外部无问题使用Django ORM?Telegram Bot运行异常求助
Let me break down what's happening here and how to fix it properly—tweaking MAX_CONNECTION and wait_timeout only addresses symptoms, not the root cause.
Why You're Seeing These Issues
The "MySQL Server has gone away" error happens because Django ORM keeps persistent database connections open by default. If your Bot sits idle for longer than MySQL's wait_timeout, the server will drop that connection silently. When your Bot tries to use the stale connection later, it throws the error.
Even if you stopped seeing the error, the underlying stale connection problem is still there—now it's probably triggering an uncaught exception that crashes your Bot process after a few hours.
Step-by-Step Fixes
1. Force Django to Refresh Connections Before Database Operations
Django has a built-in method close_old_connections() that checks for stale connections and closes them before creating new ones. Call this at the start of every message handler or background task that touches the database:
from django.db import close_old_connections, OperationalError import telebot bot = telebot.TeleBot("YOUR_BOT_TOKEN") @bot.message_handler(func=lambda msg: True) def handle_all_messages(message): # Clean up stale connections first close_old_connections() try: # Your ORM logic here user_profile = UserProfile.objects.get(telegram_id=message.chat.id) bot.reply_to(message, f"Welcome back, {user_profile.username}!") except OperationalError: # If a connection still fails, refresh again and retry close_old_connections() user_profile = UserProfile.objects.get(telegram_id=message.chat.id) bot.reply_to(message, f"Welcome back, {user_profile.username}!") except UserProfile.DoesNotExist: bot.reply_to(message, "Let's set up your profile first!") bot.polling(none_stop=True)
2. Configure Django's Connection Lifetime
Set CONN_MAX_AGE in your Django settings.py to limit how long connections stay open. This tells Django to automatically recycle connections after a set time (e.g., 5 minutes = 300 seconds), preventing them from hitting MySQL's timeout:
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'your_database', 'USER': 'your_db_user', 'PASSWORD': 'your_db_pass', 'HOST': 'localhost', 'PORT': '3306', # Auto-recycle connections after 5 minutes 'CONN_MAX_AGE': 300, } }
3. Add Exception Handling to Prevent Crashes
Even with the above fixes, network blips can still cause database errors. Wrap all ORM operations in try-except blocks to catch OperationalError (Django's error for connection issues) and handle gracefully instead of letting the Bot crash.
4. Ditch the wait_timeout/MAX_CONNECTION Tweaks (They're Not Needed)
MAX_CONNECTIONcontrols MySQL's total concurrent connections—your Bot is unlikely to hit this limit unless you're running hundreds of parallel tasks.wait_timeoutonly delays the problem, not solves it. If your Bot is idle longer than this value, you'll be back to square one.
Bonus: Use a Process Manager for Safety
Even with perfect fixes, occasional crashes can happen (e.g., Telegram API outages). Use tools like supervisor or systemd to run your Bot as a service—they'll automatically restart it if it crashes, keeping it online 24/7.
内容的提问来源于stack exchange,提问作者Vova Pytsyuk

