Help us understand the problem. What is going on with this article?

Python + MySQL でコネクションプーリング

Python で MySQL とのコネクションプーリングを行う方法と、そのハマりどころについて。

mysql-connector-python の MySQLConnectionPool の問題

まず、MySQL 公式の Python クライアント mysql-connector-python で単純にコネクションを作成する場合は以下のように書ける。

import mysql.connector

cnx = mysql.connector.connect(host="...", user="...", password="...", database="...")

この mysql-connector-python には MySQLConnectionPool というクラスが用意されており、これを使うと簡単にコネクションプーリングができる。1

from mysql.connector.pooling import MySQLConnectionPool

cnxpool = MySQLConnectionPool(host="...", user="...", password="...", database="...", pool_size=10)

cnx = cnxpool.get_connection()

cnx.close()  # 実際にはコネクションは切断されず、コネクションプールにリリースされる

めでたしめでたし・・・とはいかない。

試しに以下のコードを実行してみる。

from mysql.connector.pooling import MySQLConnectionPool

cnxpool = MySQLConnectionPool(host="...", user="...", password="...", database="...", pool_size=3)

cnxpool.get_connection()
cnxpool.get_connection()
cnxpool.get_connection()
cnxpool.get_connection()  #=> PoolError: Failed getting connection; pool exhausted

MySQLConnectionPool はプールのコネクションが枯渇した場合、例外を投げる仕様となっている。

このシンプルな仕様は嫌いではないのだけど、実際に Web アプリケーションなどで利用する際は「他のコネクションがリリースされるまで待つ」ような挙動であってくれたほうが嬉しいケースが多い。そうでないと、リクエスト処理の並列数が少しでもプールサイズを上回っただけでエラーが発生してしまう。

SQLAlchemy の QueuePool を使った解決策

この問題は、SQLAlchemy の QueuePool を使うと解決できる。2

from sqlalchemy.pool import QueuePool

cnxpool = QueuePool(lambda: mysql.connector.connect(host="...", user="...", password="...", database="..."), pool_size=10)

cnx = cnxpool.connect()

QueuePool の第一引数は「DB API に対応したコネクションオブジェクト」を返す関数ならなんでもいいらしい。汎用的ですごい。

SQLAlchemy というモジュール自体は ORM だが、今回は ORM 部分を全く使わずに QueuePool という仕組みだけを利用している。

hoto17296
ゆとりデータ分析マン
https://hoto.me/
churadata
沖縄で データ分析 / 機械学習 / Deep Learning をやっている会社です
https://churadata.okinawa/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした