You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用SQLAlchemy开发Telegram Bot遇ResourceClosedError问题求助

Fixing sqlalchemy.exc.ResourceClosedError: This Connection is closed in SQLAlchemy + Telegram Bot

Let's break down why you're hitting this error and how to fix it quickly.

The Root Cause

Your issue comes down to using a global session variable in a multi-request environment. Flask's webhook endpoint handles concurrent requests, and your current code reassigns the global session every time a webhook hits. But Telegram's message handlers (like chat_handler) don't run in lockstep with the webhook request lifecycle—by the time the handler fires, the previous global session might already be closed or reused by another request, leading to that "connection closed" error.

On top of that, SQLAlchemy Sessions are not thread-safe, so sharing them globally is a recipe for concurrency bugs like this.

Step-by-Step Fixes

1. Ditch the Global Session

Stop relying on a global session variable entirely. Instead, create a fresh Session inside your message handler for each message processing task. This ensures each operation gets its own isolated connection.

2. Rewrite Your chat_handler with a Local Session

Use a context manager (with statement) to automatically handle Session creation and cleanup. This guarantees the Session is closed properly after use, preventing connection leaks.

Here's the updated handler:

@bot.message_handler(func=lambda message: message.chat.id == config['chat_id'], content_types=['text'])
def chat_handler(message):
    # Create a fresh Session for this message handling task
    with Session() as session:
        tg_id = message.from_user.id
        in_db = session.query(ChatMessage).filter(
            ChatMessage.message_id == message.message_id).count()
        
        if in_db == 0:
            die_time = datetime.now().replace(second=0, microsecond=0) + \
                       timedelta(seconds=config['chat_message_lifetime'])
            if message.pinned_message is not None:
                die_time = None
            
            chat_mess = ChatMessage(
                user_id=None,
                advorder_id=None,
                message_id=message.message_id,
                dietime=die_time)
            
            session.add(chat_mess)
            session.commit()

3. Clean Up the Webhook Route

Remove the global session references from your /tg endpoint—you don't need them anymore:

@app.route('/tg', methods=['POST'])
def webhook():
    if flask.request.headers.get('content-type') == 'application/json':
        json_string = flask.request.get_data().decode('utf-8')
        update = telebot.types.Update.de_json(json_string)
        bot.process_new_updates([update])
        return ''
    else:
        flask.abort(403)

Also delete the global session = None line at the top of your code.

4. Optional: Use Scoped Sessions for Larger Apps

If your bot has multiple handlers that need database access, you can use scoped_session to automatically manage thread-local Sessions. This is cleaner than creating a Session in every handler:

# Replace your Session definition with this
from sqlalchemy.orm import scoped_session

Session = scoped_session(sessionmaker(bind=engine))

# Then in handlers:
@bot.message_handler(...)
def some_handler(message):
    session = Session()
    # Do your DB operations
    session.commit()
    # Clean up when done (or do this at the end of each request)
    Session.remove()

Scoped sessions ensure each thread gets its own Session, avoiding cross-request conflicts.

Why This Works

By creating a Session per message (or per thread), you eliminate shared connection state. The context manager handles closing the Session automatically, so connections are properly returned to the pool instead of being left in a closed state. This fixes the ResourceClosedError and prevents other concurrency-related bugs.

内容的提问来源于stack exchange,提问作者Vaderoff

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 03:53:28