Security News
Research
Data Theft Repackaged: A Case Study in Malicious Wrapper Packages on npm
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
A simple but not simple mysql connection pool based on PyMySQL
.
While using pymysql with python multithreading, generally we will face the questions:
pymysql.err.InternalError: Packet sequence number wrong - got 0 expected 1
connection lifetime
and pre_ping
mechanism, in case of borrow a brokend connection from the pool(such as closed by the mysql server due to wait_timeout
setting).This module contains two classes:
Connection
class: this is a subclass of pymysql.connections.Connection
. It can be used with or without a connection_pool, It used in the exact same way as pymysql. The details implementation of connection pool is hiddened (when used with a connection_pool additional actions are needed to maintain the pool).ConnectionPool
class: instance of this class represents the actual connection_pool.Using the concept of connection pool, there are also some aspects should be considered except the core features, such as:
GetConnectionFromPoolError
error directly.Luckily, this module will take care of these complicated details for you automaticly.
It also allows to create more than one connection_pool (with distinct ConnectionPool.name
attribute) to be associated with different databases.
pip install pymysql-pool
In the example below we're going to see how it works:
Create a pool with base/normal size is 2 and max size is 3, with pre_create_num=2 means will create 2 connections in the init phase:
>>> import pymysqlpool
>>> pymysqlpool.logger.setLevel('DEBUG')
>>> config={'host':'xxxx', 'user':'xxx', 'password':'xxx', 'database':'xxx', 'autocommit':True}
>>> pool1 = pymysqlpool.ConnectionPool(size=2, maxsize=3, pre_create_num=2, name='pool1', **config)
03-08 15:54:50 DEBUG: Create new connection in pool(pool1)
03-08 15:54:50 DEBUG: Create new connection in pool(pool1)
>>> pool1.size
2
>>> con1 = pool1.get_connection()
12-25 21:38:48 DEBUG: Get connection from pool(pool1)
>>> con2 = pool1.get_connection()
12-25 21:38:51 DEBUG: Get connection from pool(pool1)
>>> pool1.size
0
Now the pool is empty, and we still borrow a connection from it, with the default parameters of get_connection(), we will see :
>>> con3=pool1.get_connection()
03-08 15:57:32 DEBUG: Retry to get connection from pool(pool1)
03-08 15:57:32 DEBUG: Retry to get connection from pool(pool1)
03-08 15:57:32 DEBUG: Retry to get connection from pool(pool1)
03-08 15:57:33 DEBUG: Create new connection in pool(pool1)
above message show us: although pool is empty, but the max size isn't reached, so after several times retry, a new connection is create(now max size of pool is reached)
Let's try to get another connection from pool:
>>> con4=pool1.get_connection()
03-08 16:29:43 DEBUG: Retry to get connection from pool(pool1)
03-08 16:29:43 DEBUG: Retry to get connection from pool(pool1)
03-08 16:29:43 DEBUG: Retry to get connection from pool(pool1)
Traceback (most recent call last):
File "/Users/kai/github/pymysql-pool/pymysqlpool.py", line 176, in get_connection
conn = self._pool.pop()
IndexError: pop from an empty deque
... ...
pymysqlpool.GetConnectionFromPoolError: can't get connection from pool(pool1), retry_interval=0.1(s)
we can see that after several times retry, finally raise a exception GetConnectionFromPoolError
Now let's see the connection's behavior while calling close() method or using it 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)
>>> pool1.size
2 # as we expect
We can see that the module maintains the pool appropriately when (and only when) we call the close() method or use the Context Manager Protocol of the connection object.
We should always use either the close() method or Context Manager Protocol of the connection object. Otherwise the pool will exhaust soon.
The Context Manager Protocol
is preferred. It can achieve an effect similar to the "multiplexing", means the more Fine-Grained use of pool, also do more with less connections.
FAQs
MySQL connection pool based pymysql
We found that pymysql-pool demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Research
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
Research
Security News
Attackers used a malicious npm package typosquatting a popular ESLint plugin to steal sensitive data, execute commands, and exploit developer systems.
Security News
The Ultralytics' PyPI Package was compromised four times in one weekend through GitHub Actions cache poisoning and failure to rotate previously compromised API tokens.