基于mysql连接池的pymysql

pymysql-pool的Python项目详细描述


pymysql连接池

一个简单的基于pymysql的连接池。主要集中在多线程模式时使用pymysql,也兼容单线程模式,方便您在需要同时使用这两种模式时使用。在多线程模式下支持复用类似的特性(当使用与{{CD2}}连接时)。

问题:在python多线程中使用pymysql时,通常会遇到以下问题:

  1. 它不能与所有子线程共享由主线程创建的连接。它将导致如下错误: pymysql.err.InternalError: Packet sequence number wrong - got 0 expected 1
  2. 如果我们让每个子线程创建一个连接,并在这个子线程结束时关闭它,这是可行的,但显然会导致与mysql建立连接的高成本。

因此,我实现这个模块的目的是在多线程编程中尽可能少地创建与mysql的连接。

本模块包含两个类:

  • Connectionpymysql.connections.Connection的一个子类,它可以使用连接池,也可以不使用连接池,它的用法与pymysql完全相同。有关连接池的详细信息(当使用连接池时,应该采取其他操作来维护该池)被隐藏。
    为了方便起见,这个类提供了一个包装的execute_query()方法,该方法接受几个参数。
  • ConnectionPool的实例表示真正的连接池。

使用示例

安装

pip install pymysql-pool

多线程模式:

与单线程模式的主要区别在于我们应该保持池的状态。例如“从池获取连接”或“将连接放回池”,在这种情况下,还需要处理一些情况,例如:

  • 从池获取连接时:我们应该处理timeoutretry参数
  • 将连接放回池:如果执行查询时没有异常,则此连接可以直接返回池;但如果发生exception,则应根据此连接是否可reusable(基于异常类型)来决定是否应返回池。如果连接不应该返回到池,我们将其关闭并重新创建一个新连接,然后将其放到池中。

幸运的是,这个模块会自动处理这些复杂的细节。

还可以创建多个连接池(具有不同的ConnectionPool.name属性)以与不同的数据库关联。

在下面的示例中,我们将看到它如何在连接池功能中工作:

>>> import pymysqlpool
>>> pymysqlpool.logger.setLevel('DEBUG')
>>> config={'host':'xxxx', 'user':'xxx', 'password':'xxx', 'database':'xxx', 'autocommit':True}

### Create a connection pool with 2 connection in it
>>> pool1 = pymysqlpool.ConnectionPool(size=2, name='pool1', **config)
>>> pool1.size()
2
>>> con1 = pool1.get_connection()
2017-12-25 21:38:48    DEBUG: Get connection from pool(pool1)
>>> con2 = pool1.get_connection()
2017-12-25 21:38:51    DEBUG: Get connection from pool(pool1)
>>> pool1.size()
0

### We can prophesy that here will occur some exception, because the pool1 is empty
>>> con3 = pool1.get_connection(timeout=0, retry_num=0)
Traceback (most recent call last):
  File "e:\github\pymysql-pool\pymysqlpool.py", line 115, in get_connection
    conn = self._pool.get(timeout=timeout) if timeout > 0 else self._pool.get_nowait()
queue.Empty

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<pyshell#37>", line 1, in <module>
    con3 = pool1.get_connection(timeout=0, retry_num=0)
  File "e:\github\pymysql-pool\pymysqlpool.py", line 128, in get_connection
    self.name, timeout, total_times))
pymysqlpool.GetConnectionFromPoolError: can't get connection from pool(pool1) within 0*1 second(s)

### Now let's see the connection's behavior when call close() method and use with Context Manager Protocol
>>> con1.close()
2017-12-25 21:39:56    DEBUG: Put connection back to pool(pool1)
>>> with con1 as cur:
	cur.execute('select 1+1')

1
2017-12-25 21:40:25    DEBUG: Put connection back to pool(pool1)
### We can see that the module maintain the pool appropriate when(and only when) we call the close() method or use the Context Manager Protocol of connection object.

注意1:我们应该始终使用连接对象的close()方法或上下文管理器协议之一,否则池将很快耗尽。
{STR 1 } $注2:< /强>上下文管理器协议是首选的,它可以实现“复用”类似的效果。 注意3:使用close()方法时,注意不要多次使用连接对象的close()方法(您知道为什么~)。

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
java需要设置框架。可设置大小(false)以重新绘制()   java我对PDF文件感到困惑   为什么是太阳。jvm。热点。调试器。DebuggerException:无法打开二进制文件`?   设置结果为textview时出现java空指针异常   我应该使用什么同步原语在Java中实现事件驱动程序框架?   java为什么WindowClosing处理程序在退出程序之前不执行后台任务?   如何将“20170712T18:43:04.000Z”转换为安卓或java中的相对时间?   Java,获取按键的时间长度,currentTimeMillies()始终为24   maven构建的java可执行Jar找不到logback。xml   java在其外部的函数中使用for循环中的值   java如何以表格格式将不同长度的数据对齐   java Play 2.5 WebSocket连接构建   maven而非eclipse的java强制转换问题   java如何在JFreeChart中使X轴上的值水平?   构建Java Windows应用程序以访问在线MySQL数据库需要什么   java添加构造函数会出错吗?这没有道理,请帮忙,编程问题   java在一个jframe中的两个JPanel中使用两个绘制方法   java数学或逻辑问题   java如何复制Androids库存摄像头方向更改