如何恰当的关闭sqlalchemy数据库连接

1.疑问来源

时常使用 sqlalchemy 建立 engine 连接 mysql 或者 postgres ,然后利用 pandas 与数据库进行交互。一般情况下,使用结束后,就随手将 jupyter notebook 关闭了,从来没有刻意的去管 sqlalchemy engine 没有关闭后,是否会造成数据库资源浪费的问题,于是就有了这个疑问。

2.疑问解决

to be continued

前期结论:

  1. 如果不是疯狂的建立连接,MySQL/Postgreps 会自动关闭连接。

3.资料汇总

3.1 con.close() vs con.dispose()

Q1:

  • pandas.read_sql 函数中,执行完毕后,con参数(SQLAlchemy connectable)是否会释放资源——con.close()
  • 整体 python 脚本执行结束后,有无必要释放 con —— con.dispose()
  • SQLAlchemy create_engine 的 engine 是什么?
pandas.read_sql(sql, con, index_col=None, coerce_float=True, params=None, parse_dates=None, columns=None, chunksize=None)
    
con : SQLAlchemy connectable (engine/connection) or database string URI
or DBAPI2 connection (fallback mode)
Using SQLAlchemy makes it possible to use any DB supported by that library. If a DBAPI2 object, only sqlite3 is supported.

3.1.1 引子——他山之石

来自 python如何正确关闭数据库的链接,尤其sqlalchemy connection in MySQL
from sqlalchemy import create_engine
dataIn2File.to_sqldataIn2File为 pandas 的 DataFrame 数据类型

现在,基本上大家都采用python3。而python3中,用的较多的模块是sqlalchemy ,来链接mysql。然而,一般的例子中都没有涉及关闭链接。

例如:

conn = create_engine('mysql+pymysql:user:passwd@host:port/db?charset=etf-8')
try:
    dataIn2File.to_sql(table_name,con=conn,if_exists='append',index=False)
except Exception as ee:
    logger.error('fileToMysql fialed',ee)
    traceback.print_exc()

以上代码就没有关闭过conn,导致数据库的链接越来越多,最后无法新建链接。
查询过相关知识,发现了以下两种方式:

conn = create_engine('mysql+pymysql:user:passwd@host:port/db?charset=etf-8')
con = conn.connect()
try:
    dataIn2File.to_sql(table_name,con=con,if_exists='append',index=False)
except Exception as ee:
    logger.error('fileToMysql fialed',ee)
    traceback.print_exc()
finally:
    con.close()

或者

conn = create_engine('mysql+pymysql:user:passwd@host:port/db?charset=etf-8')
con = conn.connect()
try:
    dataIn2File.to_sql(table_name,con=con,if_exists='append',index=False)
except Exception as ee:
    logger.error('fileToMysql fialed',ee)
    traceback.print_exc()
finally:
    con.close()

然而,事实上,链接依旧没有关闭。若要真正关闭链接,则需要采用:conn.dispose()

conn = create_engine('mysql+pymysql:user:passwd@host:port/db?charset=etf-8')
try:
    dataIn2File.to_sql(table_name,con=conn,if_exists='append',index=False)
except Exception as ee:
    logger.error('fileToMysql fialed',ee)
    traceback.print_exc()
finally:
    conn.dispose()

经过1个小时多的探索,终于大功告成。

3.2 Google 探索

Search word:

  1. how long postgres auto close connection
  2. how long mysql auto close connection

3.2.1 MySQL自动关闭空闲连接时间

MySQL默认自动关闭连接时间(interactive_timeout, wait_timeout )为8小时
How long is “too long” for MySQL Connections to sleep?

mysqld will timeout database connections based on two server options:

1. interactive_timeout
The number of seconds the server waits for activity on an interactive connection before closing it. An interactive client is defined as a client that uses the CLIENT_INTERACTIVE option to mysql_real_connect(). See also wait_timeout.
2. wait_timeout
The number of seconds the server waits for activity on a noninteractive connection before closing it.
On thread startup, the session wait_timeout value is initialized from the global wait_timeout value or from the global interactive_timeout value, depending on the type of client (as defined by the CLIENT_INTERACTIVE connect option to mysql_real_connect()). See also interactive_timeout.

Both are 28,800 seconds (8 hours) by default.

You can set these options in /etc/my.cnf

If your connections are persistent (opened via mysql_pconnect) you could lower these numbers to something reasonable like 600 (10 minutes) or even 60 (1 minute). Or, if your app works just fine, you can leave the default. This is up to you.

You must set these as follows in my.cnf (takes effect after mysqld is restarted):

[mysqld]
interactive_timeout=180
wait_timeout=180

If you do not want to restart mysql, then run these two commands:

SET GLOBAL interactive_timeout = 180;
SET GLOBAL wait_timeout = 180;

This will not close the connections already open. This will cause new connections to close in 180 seconds.

4.资料链接

  • 10
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
个步骤: 1. 找到链表尾部节点的前一个节点。 ```c struct Node* prevNode = *head; while (prevNode->next->next != NULL) { prevNode = prevNode->next; } ``` 2. 找到SQLAlchemy是一个流行的Python ORM框架,它提供了一个灵活的数据库连接池。连接池是一种链表尾部节点。 ```c struct Node* delNode = prevNode->next; ``` 3. 将前一个节点的技术,它可以提高数据库操作的性能和可靠性。它通过维护一定数量的数据库连接来避免频繁地打开和关闭数据库连接,从而提高效率。 下面是SQLAlchemy连接池的一些原指针域设置为`NULL`。 ```c prevNode->next = NULL; ``` 4. 释放被删除节点理说明: 1. SQLAlchemy连接池是基于Python标准库中的Queue模块实现的。连接池是一个队的内存空间。 ```c free(delNode); ``` 完整代码如下: ```c void deleteAtTail(struct列,其中每个元素都是一个数据库连接对象。 2. 当客户端请求一个数据库连接时,连接池会 Node** head) { if (*head == NULL) { return; } if ((*head)->next == NULL) { 从队列中获取一个空闲连接对象。如果队列为空,连接池会创建一个新的连接对象,并将其加 free(*head); *head = NULL; return; } struct Node* prevNode = *head; while (prev入队列。 3. 客户端使用完连接对象后,必须将其还回连接池中。连接池会将Node->next->next != NULL) { prevNode = prevNode->next; } struct Node* delNode = prevNode连接对象标记为可用,然后将其放回队列中。 4. 如果连接池中的连接对象数量超->next; prevNode->next = NULL; free(delNode); } ``` ## 5. 动态链表的修改过了设定的上限,连接池会将多余的连接对象关闭,以避免资源浪费。 5. SQLAlchemy连接池还提供了一些高级功能,比如连接池中连接对象的自动重连、超时控制 动态链表的修改操作需要完成以下几个步骤: 1. 找到待修改节点。 ```c struct Node、连接对象状态检查等。 总之,SQLAlchemy连接池是一种非常有用的技术,可以提高* currNode = *head; while (currNode != NULL && currNode->data != oldData) { currNode = currNode数据库操作的性能和可靠性。它可以避免频繁地打开和关闭数据库连接,从而节省资源和时间。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值