首页 > 解决方案 > 缓存/重用数据库连接以供以后查看使用

问题描述

我正在保存用户的数据库连接。在他们第一次输入凭据时,我会执行以下操作:

self.conn = MySQLdb.connect (
    host = 'aaa',
    user = 'bbb',
    passwd = 'ccc',
    db = 'ddd',
    charset='utf8'
)
cursor = self.conn.cursor()
cursor.execute("SET NAMES utf8")
cursor.execute('SET CHARACTER SET utf8;')
cursor.execute('SET character_set_connection=utf8;')

然后我就可以conn开始处理所有用户的查询了。但是,我不想每次view加载时都重新连接。我将如何存储这个“开放连接”,以便我可以在视图中执行以下操作:

def do_queries(request, sql):
    user = request.user
    conn = request.session['conn']
    cursor = request.session['cursor']
    cursor.execute(sql)

更新:似乎上述方法是不可能的,也不是好的做法,所以让我重新表述一下我正在尝试做的事情:

我有一个用户可以在输入凭据后使用的 sql 编辑器(想想 Navicat 或 SequelPro 之类的东西)。请注意,这不是默认的 django db 连接——我事先不知道凭据。现在,一旦用户“连接”,我希望他们能够进行尽可能多的查询,而不必每次他们这样做时都重新连接。例如——再次重复——像 Navicat 或 SequelPro。这将如何使用 python、django 或 mysql 完成?也许我真的不明白这里有什么必要(缓存连接?连接池?等),所以任何建议或帮助将不胜感激。

标签: pythonsqldatabasedatabase-connectionconnection-pooling

解决方案


您可以使用 IoC 容器为您存储单例提供程序。本质上,它不会每次都构造一个新的连接,它只会构造一次(第一次ConnectionContainer.connection_provider()被调用),然后它总是会返回之前构造的连接。

您需要该dependency-injector软件包才能使我的示例正常工作:

import dependency_injector.containers as containers
import dependency_injector.providers as providers


class ConnectionProvider():
    def __init__(self, host, user, passwd, db, charset):
        self.conn = MySQLdb.connect(
            host=host,
            user=user,
            passwd=passwd,
            db=db,
            charset=charset
        )


class ConnectionContainer(containers.DeclarativeContainer):
    connection_provider = providers.Singleton(ConnectionProvider,
                                              host='aaa',
                                              user='bbb',
                                              passwd='ccc',
                                              db='ddd',
                                              charset='utf8')


def do_queries(request, sql):
    user = request.user
    conn = ConnectionContainer.connection_provider().conn
    cursor = conn.cursor()
    cursor.execute(sql)

我在这里对连接字符串进行了硬编码,但也可以根据可更改的配置使其可变。在这种情况下,您还可以为配置文件创建一个容器,并让连接容器从那里读取其配置。然后在运行时设置配置。如下:

import dependency_injector.containers as containers
import dependency_injector.providers as providers

class ConnectionProvider():
    def __init__(self, connection_config):
        self.conn = MySQLdb.connect(**connection_config)

class ConfigContainer(containers.DeclarativeContainer):
    connection_config = providers.Configuration("connection_config")

class ConnectionContainer(containers.DeclarativeContainer):
    connection_provider = providers.Singleton(ConnectionProvider, ConfigContainer.connection_config)

def do_queries(request, sql):
    user = request.user
    conn = ConnectionContainer.connection_provider().conn
    cursor = conn.cursor()
    cursor.execute(sql)


# run code
my_config = {
    'host':'aaa',
    'user':'bbb',
    'passwd':'ccc',
    'db':'ddd',
    'charset':'utf8'
}

ConfigContainer.connection_config.override(my_config)
request = ...
sql = ...

do_queries(request, sql)

推荐阅读