python中数据库连接池DBUtils
DBUtils简介
DBUtils是Python的一个用于实现数据库连接池的模块。
应用场景:只要我们要写原生SQL,特别是用Flask的时候,用户连接数据库就可以用连接池的形式来查询数据或插入数据。
使用方法
创建一批连接到连接池,供所有线程共享使用
配置文件:
from datetime import timedelta from redis import Redis import pymysql from dbutils.pooled_db import PooledDB class Config(object): DEBUG = True SECRET_KEY = '666666' PERMANENT_SESSION_LIFETIME = timedelta(minutes=20) SESSION_REFRESH_EACH_REQUEST = True SESSION_TYPE = 'redis' SESSION_REDIS = Redis(host='127.0.0.1', port=6379) PYMYSQL_POOL = PooledDB( creator=pymysql, # 使用链接数据库的模块 maxconnections=6, # 连接池允许的最大连接数,0和None表示不限制连接数 mincached=2, # 初始化时,链接池中至少创建的空闲的链接,0表示不创建 maxcached=5, # 链接池中最多闲置的链接,0和None不限制 maxshared=3, # 链接池中最多共享的链接数量,0和None表示全部共享。 # PS: 无用,因为pymysql和MySQLdb等模块的 threadsafety都为1, # 所有值无论设置为多少,_maxcached永远为0,所以永远是所有链接都共享。 blocking=True, # 连接池中如果没有可用连接后,是否阻塞等待。True,等待;False,不等待然后报错 maxusage=None, # 一个链接最多被重复使用的次数,None表示无限制 setsession=[], # 开始会话前执行的命令列表。如:["set datestyle to ...", "set time zone ..."] ping=0, # ping MySQL服务端,检查是否服务可用。# 如:0 = None = never, 1 = default = whenever # it is requested, 2 = when a cursor is created, 4 = when a query is executed, 7 = always host='127.0.0.1', port=3306, user='root', password='', database='userinfo1', charset='utf8' )
使用连接池时,可以通过一个SQLHelper的类来拿去数据:
import pymysql
# 这个Config就是配置文件中配置的类。 from settings import Config class SQLHelper(object): @staticmethod def open(cursor): POOL = Config.PYMYSQL_POOL conn = POOL.connection() cursor = conn.cursor(cursor=cursor) return conn, cursor @staticmethod def close(conn, cursor): conn.commit() cursor.close() conn.close() @classmethod def fetch_one(cls, sql, args, cursor=pymysql.cursors.DictCursor): conn, cursor = cls.open(cursor) cursor.execute(sql, args) obj = cursor.fetchone() cls.close(conn, cursor) return obj @classmethod def fetch_all(cls, sql, args, cursor=pymysql.cursors.DictCursor): conn, cursor = cls.open(cursor) cursor.execute(sql, args) obj = cursor.fetchall() cls.close(conn, cursor) return obj @classmethod def insert_one(cls, sql, args, cursor=None): conn, cursor = cls.open(cursor) res = cursor.execute(sql, args) cls.close(conn, cursor) return res
视图要取数据时,就可以导入我们写的SQLHelper,然后使用相应的方法取数据:
@account.route('/login', methods=['GET', 'POST']) def login(): if request.method == 'GET': form = LoginForm() # 使用的时wtforms模块创建的表单验证的类 return render_template('login.html', form=form) form = LoginForm(formdata=request.form) if not form.validate(): return render_template('login.html', form=form) # 正确的数据: {'user': 'xx', 'pwd': '123'}
# 通过%(user)s的方式传值,后面就可以传一个字典,让他自动去找相应的key,并把value传进去。插入操作一样的,只要用wtforms创建的类中的字段
和数据库中字段名一样,哪怕数据库中没有这么多字段,都没有问题。 obj = SQLHelper.fetch_one('select * from users where name=%(user)s and pwd=%(pwd)s', form.data) if obj: uid = str(uuid4()) session.permanent = True session['user_info'] = {'id': uid, 'name': obj['name']} return redirect('/index') else: return render_template('login.html', msg='用户名或密码错误', form=form)