如何创建 mysql 连接池或任何更好的方法来初始化多个数据库?

How to create a mysql connection pool or any better way to initialize the multiple databases?

在我的代码中,我打开两个 mysql 连接并使用 HTTP 请求将数据插入数据库

g.db = mysql.connector.connect(user=a ,password=password, host=localhost,database=mysq1)
g.db1 = mysql.connector.connect(user=b,password=password, host=localhost,database=mysql2)

@app.route('/user/<db>')  
def insert(db):
   #code for inserting data into mysql1 database
   #code for inserting data into mysql2 database

我正在向 select 数据库发出 HTTP 请求。

  curl -i 'localhost:5000/user/mysql1' #

运行良好,正在将数据插入 selected 数据库。 但是我想为这两个连接创建一个连接池,然后使用那个池。

问题:

  1. 如何实现mysql连接池?

  2. 是否有其他更好的初始化方法 connections.Currently 连接在每次请求时打开。

使用 ORM 框架使事情变得更容易,下面是我们在没有任何 ORM 框架的情况下创建连接池的基本和通用方法。

  1. The mysql.connector.pooling module implements pooling.

  2. A pool opens a number of connections and handles thread safety when providing connections to requesters.

  3. The size of a connection pool is configurable at pool creation time. It cannot be resized thereafter.

创建自己的池并命名,myPool在连接池的参数中,你也可以声明池大小= 5(这是数据库连接数)。

更多信息请看下面:

dbconfig = {
  "database": "test",
  "user":     "joe"
}

cnx = mysql.connector.connect(pool_name = "mypool",
                              pool_size = 3,
                              **dbconfig)

dbconfig,数据库配置是您每次更改数据库时提供所有配置详细信息的地方。事实上,如果你愿意,你可以拥有多个数据库。

请看这个MySQL documentation here

我们可以看到更多关于如何声明这个参数的信息:

MySQLConnectionPool(pool_name=None,
                    pool_size=5,
                    pool_reset_session=True,
                    **kwargs)

此构造函数实例化一个管理连接池的对象。

参数详细:

1. pool_name: The pool name. If this argument is not given, Connector/Python automatically generates the name, composed from whichever of the host, port, user, and database connection arguments are given in kwargs, in that order.

It is not an error for multiple pools to have the same name. An application that must distinguish pools by their
**pool_name** property should create each pool with a distinct name.

2. pool_size: The pool size. If this argument is not given, the default is 5.

你应该看到一些不错的文档 here

为了使您的连接池成为多线程的,stackoverflw 上的 post 可能真的有帮助。请看这个post

#!/usr/bin/python
# -*- coding: utf-8 -*-
import time
import mysql.connector.pooling


dbconfig = {
    "host":"127.0.0.1",
    "port":"3306",
    "user":"root",
    "password":"123456",
    "database":"test",
}


class MySQLPool(object):
    """
    create a pool when connect mysql, which will decrease the time spent in 
    request connection, create connection and close connection.
    """
    def __init__(self, host="172.0.0.1", port="3306", user="root",
                 password="123456", database="test", pool_name="mypool",
                 pool_size=3):
        res = {}
        self._host = host
        self._port = port
        self._user = user
        self._password = password
        self._database = database

        res["host"] = self._host
        res["port"] = self._port
        res["user"] = self._user
        res["password"] = self._password
        res["database"] = self._database
        self.dbconfig = res
        self.pool = self.create_pool(pool_name=pool_name, pool_size=pool_size)

    def create_pool(self, pool_name="mypool", pool_size=3):
        """
        Create a connection pool, after created, the request of connecting 
        MySQL could get a connection from this pool instead of request to 
        create a connection.
        :param pool_name: the name of pool, default is "mypool"
        :param pool_size: the size of pool, default is 3
        :return: connection pool
        """
        pool = mysql.connector.pooling.MySQLConnectionPool(
            pool_name=pool_name,
            pool_size=pool_size,
            pool_reset_session=True,
            **self.dbconfig)
        return pool

    def close(self, conn, cursor):
        """
        A method used to close connection of mysql.
        :param conn: 
        :param cursor: 
        :return: 
        """
        cursor.close()
        conn.close()

    def execute(self, sql, args=None, commit=False):
        """
        Execute a sql, it could be with args and with out args. The usage is 
        similar with execute() function in module pymysql.
        :param sql: sql clause
        :param args: args need by sql clause
        :param commit: whether to commit
        :return: if commit, return None, else, return result
        """
        # get connection form connection pool instead of create one.
        conn = self.pool.get_connection()
        cursor = conn.cursor()
        if args:
            cursor.execute(sql, args)
        else:
            cursor.execute(sql)
        if commit is True:
            conn.commit()
            self.close(conn, cursor)
            return None
        else:
            res = cursor.fetchall()
            self.close(conn, cursor)
            return res

    def executemany(self, sql, args, commit=False):
        """
        Execute with many args. Similar with executemany() function in pymysql.
        args should be a sequence.
        :param sql: sql clause
        :param args: args
        :param commit: commit or not.
        :return: if commit, return None, else, return result
        """
        # get connection form connection pool instead of create one.
        conn = self.pool.get_connection()
        cursor = conn.cursor()
        cursor.executemany(sql, args)
        if commit is True:
            conn.commit()
            self.close(conn, cursor)
            return None
        else:
            res = cursor.fetchall()
            self.close(conn, cursor)
            return res


if __name__ == "__main__":
    mysql_pool = MySQLPool(**dbconfig)
    sql = "select * from store WHERE create_time < '2017-06-02'"

    # test...
    while True:
        t0 = time.time()
        for i in range(10):
            mysql_pool.execute(sql)
            print i
        print "time cousumed:", time.time() - t0

你可以在开头用create_pool()创建一个连接池,最后导致MySQLConnectionPool(),当你需要连接到MySQL时,你可以用get_connection() 从池中,当您不需要连接时,您可以使用 conn.close().

将连接添加回池中