【问题标题】:How can I trace SQLAlchemy table connection / locks如何跟踪 SQLAlchemy 表连接/锁
【发布时间】:2021-03-20 01:44:47
【问题描述】:

我有一个烧瓶例程,它有一个相当简单的 Flask-SQLAlchemy 数据库结构,包括用户和其他一些简单的表。为了在 AWS 中运行我的烧瓶站点,我为 python/flask GUI 独立编写了一个 docker,以及一个单独的 docker 来托管 MySQL 数据库(具有永久存储)。

我遇到的挑战似乎是挥之不去的联系。最初,我收到了一些连接错误:

TimeoutError: QueuePool limit of size 25 overflow 15 reached, connection timed out, timeout 30 (Background on this error at: http://sqlalche.me/e/13/3o7r)

通过添加以下修改,我能够解决这个问题(并且至少延长了我需要重新启动烧瓶 docker 的时间):

    app.config['SQLALCHEMY_POOL_SIZE'] = 80
    app.config['SQLALCHEMY_MAX_OVERFLOW'] = 20
    app.config['SQLALCHEMY_POOL_RECYCLE'] = 1800

我还尝试通过在各种数据库访问后添加 db.close() 语句来解决,但我的用户名访问/会话变量停止正常运行以保留页面之间的用户身份。

最后,因为我使用了与数据库访问互连的 SSE 流(如下),所以我提高了 pool_size 和 max_overflow 值并获得了一些额外的正常运行时间。我的想法是,用户应该只在流页面上停留一段有限的时间,并且我的超时限制会在一段时间后关闭数据库并返回池连接。

@games.route('/stream_game_play_channel')
def stream_game_play_channel():
    @stream_with_context
    def eventStream():
        channel = session.get('channel')
        game_id = int(left(channel, 5))
        cnt = 0
        while cnt < 1000:
            #print(f'cnt = 0 process running from: {current_user.username}')
            time.sleep(0.5)
            ntime = redisChannel.get(channel)
            #print(f'Still running...{ntime}')
            if cnt == 0:
                msgs = db.session.query(Messages).filter(Messages.game_id == game_id) \
                    .filter(Messages.type == 'gamePlay')
                db.session.close()
                msg_list = [f'{i.msg_from:>20}: {i.message}' for i in msgs]
                cnt += 1
                ltime = ntime
                lmsg_list = msg_list
                for i in msg_list:
                    yield "data: {}\n\n".format(i)
            elif ntime != ltime:
                #print(f'cnt > 0 process running from: {current_user.username}')
                #time.sleep(1)
                db.session.commit()
                msgs = db.session.query(Messages).filter(Messages.game_id == game_id) \
                    .filter(Messages.type == 'gamePlay')
                db.session.close()
                msg_list = [f'{i.msg_from:>20}: {i.message}' for i in msgs]

                for i in itertools.islice(msg_list, len(lmsg_list), len(msg_list)):
                    yield "data: {}\n\n".format(i)
                lmsg_list = msg_list
                ltime = ntime

                cnt += 1
    return Response(eventStream(), mimetype="text/event-stream")

不幸的是,通过进一步增加池大小,我现在看到我的 MySQL 数据库达到了限制。

sqlalchemy.exc.OperationalError: (pymysql.err.OperationalError) (1040, 'Too many connections')

如何开始诊断我的代码的哪些部分没有回收池连接?

【问题讨论】:

    标签: python flask sqlalchemy


    【解决方案1】:

    我的解决方案是修改我的连接引擎以引用会话:

    report_mktgsales_df = pd.read_sql_query(sql_code, con=db.session.bind).drop(columns=['company'])
    

    在此之前,我一直在使用“db.engine”,这留下了未关闭的连接。

    【讨论】:

      猜你喜欢
      • 2014-01-27
      • 1970-01-01
      • 1970-01-01
      • 2015-03-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-28
      • 1970-01-01
      相关资源
      最近更新 更多