基于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用变化的替换字符串替换子字符串   从数据库中断中恢复的oracle Java DAL?   Android/Java页边距位于左/右/底部   java如何用相同的源代码构建不同的APK?(我发现了一个错误)   java正则表达式,仅当字符串以一行中的3个数字开头时才匹配第一个数字   使用以xml为输入的给定端点调用java中的rest-ful web服务?   java长字符串转换为UTF8引发异常   java如何使用截取方法获取ArrayList   java将计算列添加到可观察列表中   正则表达式如何在java正则表达式中使用组?   java正则表达式只接受字母表和空格,不允许在字符串的开头和结尾使用空格   java简单onclick按钮在安卓中不起作用   java如何在Spring中只实现Crudepository的特定方法?   java无法使用json对象NPE读取jsonarray   java我可以添加maven依赖项,这些依赖项被打包为除此之外的任何东西。罐子