CheckBox和richTextBox
python编程中可以使用pymysql进行数据库连接及增删改查操作,但每次连接mysql请求时,都是独立的去请求访问,比较浪费资源,而且访问数量达到一定数量时,对mysql的性能会产生较大的影响。因此实际使用中,通常会使用数据库的连接池技术,来访问数据库达到资源复用。
python的数据库连接池包:DBUtils --仅提供给了连接池管理,实际的数据库操作依然是由符合 DB-API 2 标准的目标数据库模块完成的。
DBUtils提供两种外部接口:
- PersistentDB:提供线程专用的数据库连接,并自动管理连接。
- PooledDB:提供进程内所有线程共享的数据库连接池,并自动管理连接。
DBUtils包安装: pip3 install DBUtils
或者下载 DBUtils 安装包,解压后,使用python setup.py install 命令进行安装
实测证明 PersistentDB 的速度是最高的,但是在某些特殊情况下,数据库的连接过程可能异常缓慢,而此时的PooledDB则可以提供相对来说平均连接时间比较短的管理方式。
另外,实际使用的数据库驱动也有所依赖,比如SQLite数据库只能使用PersistentDB作连接池。 下载地址:http://www.webwareforpython.org/downloads/DBUtils/
使用方法
连接池对象只初始化一次,一般可以作为模块级代码来确保。 PersistentDB的连接例子:
import DBUtils.PersistentDB
persist=DBUtils.PersistentDB.PersistentDB(dbpai=MySQLdb,maxusage=1000,**kwargs)
这里的参数dbpai指使用的底层数据库模块,兼容DB-API的。maxusage则为一个连接最大使用次数,参考了官方例子。后面的**kwargs则为实际传递给MySQLdb的参数。
获取连接: conn=persist.connection() 实际编程中用过的连接直接关闭 conn.close() 即可将连接交还给连接池。
PooledDB使用方法同PersistentDB,只是参数有所不同。
- dbapi :数据库接口
- mincached :启动时开启的空连接数量
- maxcached :连接池最大可用连接数量
- maxshared :连接池最大可共享连接数量
- maxconnections :最大允许连接数量
- blocking :达到最大数量时是否阻塞
- maxusage :单个连接最大复用次数
- setsession :用于传递到数据库的准备会话,如 [”set name UTF-8″] 。
未使用连接池的数据库方法:
import MySQLdb
conn= MySQLdb.connect(host='localhost',user='root',passwd='pwd',db='myDB',port=3306)
#import pymysql
#conn = pymysql.connect(host='localhost', port='3306', db='game', user='root', password='123456', charset='utf8')
cur=conn.cursor()
SQL="select * from table1"
r=cur.execute(SQL)
r=cur.fetchall()
cur.close()
conn.close()
def getconn(host, user, passwd, db, sql, port=3306,charset='utf8'):
conn = pymysql.connect(host=host, user=user, passwd=passwd, port=port, db=db, charset=charset) #建立连接
cur = conn.cursor(cursor=pymysql.cursors.DictCursor) #建立游标并指定游标类型
cur.execute(sql) #执行sql
if sql.startswith('select'): #判断sql是否是select
res = cur.fetchone()
else:
conn.commit() #insert\delete\update语句执行完毕后需要进行commit
res = 88
cur.close() #关闭游标
conn.close() #关闭连接
return res
用数据库连接池后的方法:
import MySQLdb
from DBUtils.PooledDB import PooledDB
pool = PooledDB(MySQLdb,5,host='localhost',user='root',passwd='pwd',db='myDB',port=3306) #5为连接池里的最少连接数 conn = pool.connection() #以后每次需要数据库连接就是用connection()函数获取连接就好了
cur=conn.cursor()
SQL="select * from table1"
r=cur.execute(SQL)
r=cur.fetchall()
cur.close()
conn.close()
测试代码:
import sys
import threading
import MySQLdb
import DBUtils.PooledDB connargs = { "host":"localhost", "user":"user1", "passwd":"123456", "db":"test" }
def test(conn):
try:
cursor = conn.cursor()
count = cursor.execute("select * from users")
rows = cursor.fetchall()
for r in rows: pass
finally:
conn.close() def testloop():
print ("testloop")
for i in range(1000):
conn = MySQLdb.connect(**connargs)
test(conn) def testpool():
print ("testpool")
pooled = DBUtils.PooledDB.PooledDB(MySQLdb, **connargs)
for i in range(1000):
conn = pooled.connection()
test(conn) def main():
t = testloop if len(sys.argv) == 1 else testpool
for i in range(10):
threading.Thread(target = t).start() if __name__ == "__main__":
main()
看看 10 线程的测试结果。
$ time ./main.py
testloop
testloop
testloop
testloop
testloop
testloop
testloop
testloop
testloop
testloop
real 0m4.471s
user 0m0.570s
sys 0m4.670s
$ time ./main.py -l
testpool
testpool
testpool
testpool
testpool
testpool
testpool
testpool
testpool
testpool
real 0m2.637s
user 0m0.320s
sys 0m2.750s
虽然测试方式不是很严谨,但从测试结果还是能感受到 DBUtils 带来的性能提升。当然,我们我们也可以在 testloop() 中一直重复使用一个不关闭的 Connection,但这却不适合实际开发时的情形。
DBUtils 提供了几个参数,便于我们更好地调整资源利用。
DBUtils.PooledDB.PooledDB(self, creator,
mincached=0, maxcached=0, maxshared=0, maxconnections=0, blocking=False, maxusage=None,
setsession=None, failures=None, *args, **kwargs)
Docstring:
Set up the DB-API 2 connection pool.
creator: either an arbitrary function returning new DB-API 2
connection objects or a DB-API 2 compliant database module
mincached: initial number of idle connections in the pool
(0 means no connections are made at startup)
maxcached: maximum number of idle connections in the pool
(0 or None means unlimited pool size)
maxshared: maximum number of shared connections
(0 or None means all connections are dedicated)
When this maximum number is reached, connections are
shared if they have been requested as shareable.
maxconnections: maximum number of connections generally allowed
(0 or None means an arbitrary number of connections)
blocking: determines behavior when exceeding the maximum
(if this is set to true, block and wait until the number of
connections decreases, otherwise an error will be reported)
maxusage: maximum number of reuses of a single connection
(0 or None means unlimited reuse)
When this maximum usage number of the connection is reached,
the connection is automatically reset (closed and reopened).
setsession: optional list of SQL commands that may serve to prepare
the session, e.g. ["set datestyle to ...", "set time zone ..."]
failures: an optional exception class or a tuple of exception classes
for which the connection failover mechanism shall be applied,
if the default (OperationalError, InternalError) is not adequate
args, kwargs: the parameters that shall be passed to the creator
function or the connection constructor of the DB-API 2 module
DBUtils 仅提供给了连接池管理,实际的数据库操作依然是由符合 DB-API 2 标准的目标数据库模块完成的。
下面利用pymysql 和 DBUtils 建立自己的mysql 数据库连接工具包
class OPMysql(object): _pool = None def __init__(self):
# 构造函数,创建数据库连接、游标
self.coon = OPMysql.getmysqlconn()
self.cur = self.coon.cursor(cursor=pymysql.cursors.DictCursor) # 数据库连接池连接
@staticmethod
def getmysqlconn():
if OPMysql._pool is None:
OPMysql._pool = PooledDB(creator=pymysql, mincached=1, maxcached=20, host=mysqlInfo['host'], user=mysqlInfo['user'], passwd=mysqlInfo['passwd'], db=mysqlInfo['db'], port=mysqlInfo['port'], charset=mysqlInfo['charset'])
print(OPMysql._pool)
return OPMysql._pool.connection() # 插入\更新\删除sql
def op_insert(self, sql):
try:
# print('op_insert', sql)
insert_num = self.cur.execute(sql)
# print('mysql sucess ', insert_num)
self.coon.commit()
return insert_num
except Exception, e:
print "错误信息", e #仅仅输出错误的愿因,下面的print_exc函数内部会把堆栈信息打印出来
traceback.print_exc() #打印出错误堆栈信息 # 查询
def op_select(self, sql):
print('op_select', sql)
self.cur.execute(sql) # 执行sql
select_res = self.cur.fetchone() # 返回结果为字典
print('op_select', select_res)
return select_res #释放资源
def dispose(self):
self.coon.close()
self.cur.close()
配置文件mysqlinfo,包含数据库的连接信息、用户名密码等:
mysqlInfo = {
"host": '192.168.1.112',
"user": 'root',
"passwd": '',
"db": 'apitest',
"port": 3306,
"charset": 'utf8'
}
创建test,测试数据库连接
if __name__ == '__main__':
#申请资源
opm = OPMysql() sql = "select * from demo where name ='a' and pwd='e10adc3949ba59abbe56e057f20f883e' "
res = opm.op_select(sql) #释放资源
opm.dispose()
PooledDB参数解释:
- mincached,最少的空闲连接数,如果空闲连接数小于这个数,pool会创建一个新的连接。
- maxcached,最大的空闲连接数,如果空闲连接数大于这个数,pool会关闭空闲连接。
- maxconnections,最大的连接数,进程中最大可创建的线程数。
- blocking, 当连接数达到最大连接数时,再次请求时,如果这个值是True,请求连接的程序会一直等待,直到当前连接数小于最大连接数;如果这个值为False,会报错。
- masxshared,当连接数达到这个数时,新请求的连接会分享已经分配出去的连接。
在uwsgi中,每个http请求都会有一个进程,连接池中配置的连接数都是一个进程为单位的(即上面的最大连接数,都是在一个进程中创建的线程数),如果业务中,一个http请求中需要的sql连接数不是很多的话(其实大多数都只需要创建一个连接),配置的连接数配置都不需要太大。
连接池对性能的提升:
- 在程序创建连接的时候,可以从一个空闲的连接中获取,不需要重新初始化连接,提升获取连接的速度。
- 关闭连接的时候,把连接放回连接池,而不是真正的关闭,所以可以减少频繁的打开和关闭连接。
如何选择
PooledDB和PersistentDB都通过回收数据库连接,且即使数据库连接中断也能保持稳定性的方式从而达到提升数据库访问性能的目的。在现实场景中应该如何选择呢?对于保持常量线程数且频繁使用数据库的应用,使用PersistentDB;对于频繁开启、结束线程的应用,使用PooledDB。
其他
如果程序中使用了ORM框架,如SQLObject
或SQLAlchemy
,不需要使用DBUtils,因为这些框架自身维护了连接池。
数据库线程安全级别:
比如pymysql
就是可以共享模块但不能共享连接,查看方式pymysql.threadsafety
https://www.cnblogs.com/KKSoft/p/8040374.html
https://blog.csdn.net/xc_zhou/article/details/80893289
http://aiuxian.com/article/p-34172.html
CheckBox和richTextBox的更多相关文章
- WPF基础学习第二天(高级控件)
1.Menu菜单控件 Exp1: Code: <Window x:Class="菜单Menu.MainWindow" xmlns="http://schemas.m ...
- GroupBox、TextBox、CheckBox、ToolStrip、RichTextBox、Timer控件
GroupBox:划分窗体区域,内部可以拖放组件 TextBox:可编辑文本框,也可设置为只读 属性:ReadOnly(只读).PasswordChar(密码显示的符号,如*).Multiline(多 ...
- WPF自定义控件与样式(3)-TextBox & RichTextBox & PasswordBox样式、水印、Label标签、功能扩展
一.前言.预览 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要是对文本 ...
- WPF RichTextBox 做内容展示框 滚动条控制判定是否阅读完成
一.项目背景: 最近,做项目,因为是金融项目,客户登录交易的时候,有一个提示框,就是告知客户要“入市需谨慎”等等,想必大家都遇到这样的场景,当然,这种提示是没人会看的,不过作为交易所,这样的提示又必不 ...
- WPF自定义控件与样式(4)-CheckBox/RadioButton自定义样式
一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要内容: Che ...
- 【转】WPF自定义控件与样式(3)-TextBox & RichTextBox & PasswordBox样式、水印、Label标签、功能扩展
一.前言.预览 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等. 本文主要是对文本输入控件进行样式开发,及相关扩展功能开发,主要内容包括: 基本文 ...
- WPF CheckBox 样式
<Style x:Key="FocusVisual"> <Setter Property="Control.Template"> < ...
- 计算Div标签内Checkbox个数或已被disabled的个数
先看下面的html: 计算div内的checkbox个数:$('#divmod input[type="checkbox"]').length 计算div内checkbox被dis ...
- 前端开发:css技巧,如何设置select、radio 、 checkbox 、file这些不可直接设置的样式 。
前言: 都说程序员有三宝:人傻,钱多,死得早.博主身边的程序“猿”一大半应了这三宝,这从侧面说明了一个问题,只有理性是过不好日子的.朋友们应该把工作与生活分开,让生活变得感性,让工作变得理性,两者相提 ...
随机推荐
- Android实战简易教程-第二十八枪(基于Bmob实现头像图片设置和网络上传功能!)
上一篇我们介绍了怎样由uri转换成String ,本文就用到了上篇文章的方法.以下我们介绍一下怎样设置头像后将头像图片上传到云端的方法,本文基于Bmob提供的服务. 看一下代码:(布局文件和前两篇文章 ...
- [C++基础]那些容易被混淆的概念:函数/数组指针-指针函数/数组,类/函数模板-模板类/函数
函数指针-指针函数 函数指针的重点是指针.表示的是一个指针,它指向的是一个函数.eg: int (*pf)(); 指针函数的重点是函数.表示的是一个函数,它的返回值是指针.eg: int* fun() ...
- 格式化Curl返回的Json字符
格式化Curl返回的Json字符 学习了:https://blog.csdn.net/guijiaoba/article/details/78235523 , 使用python工具 curl xxx ...
- Xamarin C# Android for Visual Studio 平台安装笔记参考
Xamarin是Mono创始人Miguel de Icaza创建的公司,旨在让开发者可以用C#编写iOS, Android, Mac应用程序,也就是跨平台移动开发. 简介 Xamarin是基于Mono ...
- [Firebase] 4. Firebase Object related Database
The idea: This post we are going to learn how to build a Firebase Forage with object related databas ...
- mysql安装错误总结
1.若在启动mysql服务时出现如下错误,可查看错误日志找出错误原因. Error:Starting MySQL.The server quit without updating PID file ( ...
- WCF 之 生成元数据和代理
在WCF开发概述中讲解了手工方式的WCF应用,其实实际开发中使用更多的使用配置方式和元数据来实现WCF,下面我们来看一个具体的Demo,这个例子和WCF开发概述中使用的是同一个例子,只是实现方式不同, ...
- Java打包生成exe(使用exe4j和inno setup)
Java打包生成exe 生成jar 先使用eclipse生成可执行的jar[可执行的jar包含内容更全面,包括指定主类的.mf] Exe4j的使用 一定要可执行jar进行打包. Project typ ...
- [置顶] 关于Qt的学习
初学习QT,希望用此来记录学习的轨迹....... 1.Qt版本为Qt5.1.0 2.使用Qt-Creator进行变成. 3.第一个例子 打印出“Hello World” 3.1 打开Qt-Crea ...
- css background-position结合disaply:inline-block使用
$(".icon-a").on('click', function (e) { if ($(this).next().css('display') == "none&qu ...