zoukankan      html  css  js  c++  java
  • python 使用连接池 连接 mysql

    python 使用连接池 连接 mysql

    问题
    当我们在Python中连接Mysql时,每次增、删、改、查如果都申请一个数据库连接的话,当应用程序对mysql数据库请求量大时候,运行Python的机器就会大量报time  wait(我碰到的是40000+) 。这是因为每次连接mysql数据库请求时,都是独立的去请求访问(看到开发者的代码后得出结论),相当浪费资源,访问数量达到一定量时 ,运行程序的机器就报警了。

    解决办法:
    访问数据库应该使用连接池,来达到复用数据库连接的目的

    python数据库连接池使用方法:
       a、安装 DBUtils(这里是DBUtils-1.3.tar.gz包)

       b、tar -zxvf DBUtils-1.3.tar.gz

       c、cd DBUtils-1.3

       d、 python setup.py install (安装)

    连接示例:
    https://yq.aliyun.com/articles/619548?utm_content=m_1000008987

    参考链接:https://www.jianshu.com/p/c5a8cccecf32

    MySQL挑战:建立10万连接

    连接池操作示例:
    https://zhuanlan.zhihu.com/p/61050785

    安装 DBUtils:
    pip install DBUtils -i https://pypi.tuna.tsinghua.edu.cn/simple

    代码示例:

    import pymysql
    from DBUtils.PooledDB import PooledDB
    
    '''
    PooledDB() 参数含义
    
    creator:使用链接数据库的模块
    maxconnections:连接池允许的最大连接数,0和None表示没有限制
    mincached:初始化时,连接池至少创建的空闲的连接,0表示不创建
    maxcached:连接池空闲的最多连接数,0和None表示没有限制
    maxshared:连接池中最多共享的连接数量,0和None表示全部共享,ps:其实并没有什么用,因为pymsql和MySQLDB等模块中的threadsafety都为1,所有值无论设置多少,_maxcahed永远为0,所以永远是所有链接共享
    blocking:链接池中如果没有可用共享连接后,是否阻塞等待,True表示等待,False表示不等待然后报错
    setsession:开始会话前执行的命令列表
    ping:ping Mysql 服务端,检查服务是否可用
    '''
    global_pool = PooledDB(
        creator=pymysql,
        maxconnections=500,
        mincached=0,
        maxcached=20,
        maxshared=0,
        blocking=True,
        setsession=[],
        ping=5,
        host=global_db_addr,
        port=3306,
        user='xxxx',
        password='xxxxxx',
        database='xxxxx',
        charset='utf8mb4')
    
    # 以后每次需要数据库连接用 connection() 函数获取连接即可
    conn = global_pool.connection()
    
    # 使用 cursor() 方法创建一个游标对象 cursor
    cursor = conn.cursor()
    
    #sql = 'INSERT INTO ' + tbl_name + ' (`time_key`,`code`,`direct`) VALUES (%s, %s, %s);'
    #params = (dic_data["time_key"], dic_data["code"], dic_data["direct"])
    
    tbl_name = 'stock_cur_kline_sh'
    stock_code = 'SH.600161'
    time_key = '2020-02-28 00:00:00'
    
    sql = "SELECT Close FROM " + tbl_name + " where code = '" + stock_code + "' and time_key = '" + time_key + "';"
    
    try:
        # 执行SQL语句
        cursor.execute(sql)
        # 获取所有记录列表
        results = cursor.fetchall()
        for row in results:
            close = row[0]
            # 打印结果
            print("close=%f" %(close))
    except Exception as e:
        print("插入数据库异常, msg=%s" % (e))
        logging.error(traceback.format_exc())
    finally:
        print("插入数据库成功")
        cursor.close()
        conn.close()






    python3基础:操作mysql数据库

    小小小小人ksh 2018-12-10 23:16:49 64543 收藏 494
    分类专栏: python mysql
    版权
    mysql登陆

    基本操作:
    登陆:mysql -uroot -h127.0.0.1 -P3306 -p
    mysql -uroot -p(本机不用写host)
    退出mysql:ctrl+z+回车,或者exit
    端口号默认是3306,但是可以通过安装目录下的配置文件修改。

    使用流程

    引用API模块
    获取与数据库的连接
    执行sql语句与存储过程
    关闭数据库连接
    安装pymysql

    python3 与MySQL 进行交互编程需要安装 pymysql 库,故首先使用如下命令安装pymysql
    –>pip install pymysql
    如果电脑中py2和py3共存的话,安装失败时请参考之前的博客安装方法

    pymysql.connect()连接数据库函数

    代码示例:

    import pymysql
    #打开数据库连接
    conn = pymysql.connect('localhost',user = "root",passwd = "123456",db = "testdb")
    print (conn)
    print (type(conn))

    conn.cursor():获取游标

    要想操作数据库,光连接数据是不够的,必须拿到操作数据库的游标,才能进行后续的操作,比如读取数据、添加数据。通过获取到的数据库连接实例conn下的cursor()方法来创建游标。游标用来接收返回结果
    代码示例:

    import pymysql
    #打开数据库连接
    conn = pymysql.connect('localhost',user = "root",passwd = "123456",db = "testdb")
    #获取游标
    cursor=conn.cursor()
    print(cursor)

    说明:cursor返回一个游标实例对象,其中包含了很多操作数据的方法,比如执行sql语句。

    执行sql语句execute和executemany

    execute(query,args=None)
    函数作用:执行单条的sql语句,执行成功后返回受影响的行数
    参数说明:
    query:要执行的sql语句,字符串类型
    args:可选的序列或映射,用于query的参数值。如果args为序列,query中必须使用%s做占位符;如果args为映射,query中必须使用%(key)s做占位符
    executemany(query,args=None)
    函数作用:批量执行sql语句,比如批量插入数据,执行成功后返回受影响的行数
    参数说明:
    query:要执行的sql语句,字符串类型
    args:嵌套的序列或映射,用于query的参数值
    注意:
    1.数据库性能瓶颈很大一部份就在于网络IO和磁盘IO,将多个sql语句放在一起,只执行一次IO,可以有效的提升数据库性能。推荐此方法
    2.用executemany()方法一次性批量执行sql语句,固然很好,但是当数据一次传入过多到server端,可能造成server端的buffer溢出,也可能产生一些意想不到的麻烦。所以,合理、分批次使用executemany是个合理的办法

    创建数据库

    代码示例:

    '''创建数据库'''
    import pymysql
    #打开数据库连接,不需要指定数据库,因为需要创建数据库
    conn = pymysql.connect('localhost',user = "root",passwd = "123456")
    #获取游标
    cursor=conn.cursor()
    #创建pythonBD数据库
    cursor.execute('CREATE DATABASE IF NOT EXISTS pythonDB DEFAULT CHARSET utf8 COLLATE utf8_general_ci;')
    cursor.close()#先关闭游标
    conn.close()#再关闭数据库连接
    print('创建pythonBD数据库成功')

    创建表

    代码示例:

    import pymysql
    #打开数据库连接
    conn = pymysql.connect('localhost',user = "root",passwd = "123456",db = "testdb")
    #获取游标
    cursor=conn.cursor()
    print(cursor)

    #创建user表
    cursor.execute('drop table if exists user')
    sql="""CREATE TABLE IF NOT EXISTS `user` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `name` varchar(255) NOT NULL,
    `age` int(11) NOT NULL,
    PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=0"""

    cursor.execute(sql)
    cursor.close()#先关闭游标
    conn.close()#再关闭数据库连接
    print('创建数据表成功')
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    插入单条数据

    代码示例:

    '''插入单条数据'''
    import pymysql
    #打开数据库连接,不指定数据库
    conn=pymysql.connect('localhost','root','123456')
    conn.select_db('pythondb')

    cur=conn.cursor()#获取游标

    #创建user表
    cur.execute('drop table if exists user')
    sql="""CREATE TABLE IF NOT EXISTS `user` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `name` varchar(255) NOT NULL,
    `age` int(11) NOT NULL,
    PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=0"""

    cur.execute(sql)

    insert=cur.execute("insert into user values(1,'tom',18)")
    print('添加语句受影响的行数:',insert)

    #另一种插入数据的方式,通过字符串传入值
    sql="insert into user values(%s,%s,%s)"
    cur.execute(sql,(3,'kongsh',20))

    cur.close()
    conn.commit()
    conn.close()
    print('sql执行成功')

    批量插入多条数据

    代码示例:

    '''插入多条数据'''
    import pymysql
    #打开数据库连接,不指定数据库
    conn=pymysql.connect('localhost','root','123456')
    conn.select_db('pythondb')
    #获取游标
    cur=conn.cursor()

    #另一种插入数据的方式,通过字符串传入值
    sql="insert into user values(%s,%s,%s)"
    insert=cur.executemany(sql,[(4,'wen',20),(5,'tom',10),(6,'test',30)])
    print ('批量插入返回受影响的行数:',insert)
    cur.close()
    conn.commit()
    conn.close()
    print('sql执行成功')

    注意:批量插入多条sql语句采用的是executemany(sql,args)函数,返回受影响的行数。args参数是一个包含多个元组的列表,每个元组对应一条mysql中的一条数据。这里的%s不需要加引号,否则插入数据的数据会类型错误

    查询数据

    使用execute()函数得到的只是受影响的行数,并不能真正拿到查询的内容。cursor对象还提供了3种提取数据的方法:fetchone、fetchmany、fetchall.。每个方法都会导致游标动,所以必须注意游标的位置。
    cursor.fetchone():获取游标所在处的一行数据,返回元组,没有返回None
    cursor.fetchmany(size):接受size行返回结果行。如果size大于返回的结果行的数量,则会返回cursor.arraysize条数据。
    cursor. fetchall():接收全部的返回结果行。

    代码示例:fetchone

    '''fetchone'''
    import pymysql
    #打开数据库连接
    conn=pymysql.connect('localhost','root','123456')
    conn.select_db('pythondb')
    #获取游标
    cur=conn.cursor()

    cur.execute("select * from user;")
    while 1:
    res=cur.fetchone()
    if res is None:
    #表示已经取完结果集
    break
    print (res)
    cur.close()
    conn.commit()
    conn.close()
    print('sql执行成功')

    注意:从execute()函数的查询结果中取数据,以元组的形式返回游标所在处的一条数据,如果游标所在处没有数据,将返回空元组,该数据执行一次,游标向下移动一个位置。fetchone()函数必须跟exceute()函数结合使用,并且在exceute()函数之后使用

    代码示例:fetchmany
    ‘’‘fetchmany’’’
    import pymysql
    #打开数据库连接
    conn=pymysql.connect(‘localhost’,‘root’,‘123456’)
    conn.select_db(‘pythondb’)
    #获取游标
    cur=conn.cursor()

    cur.execute(“select * from user”)
    #取3条数据
    resTuple=cur.fetchmany(3)
    print(type(resTuple))
    for res in resTuple:
    print (res)

    cur.close()
    conn.commit()
    conn.close()
    print(‘sql执行成功’)

    注意:从exceute()函数结果中获取游标所在处的size条数据,并以元组的形式返回,元组的每一个元素都也是一个由一行数据组成的元组,如果size大于有效的结果行数,将会返回cursor.arraysize条数据,但如果游标所在处没有数据,将返回空元组。查询几条数据,游标将会向下移动几个位置。fetmany()函数必须跟exceute()函数结合使用,并且在exceute()函数之后使用

    代码示例:fetchall
    ‘’‘fetchall’’’
    import pymysql
    #打开数据库连接
    conn=pymysql.connect(‘localhost’,‘root’,‘123456’)
    conn.select_db(‘pythondb’)
    #获取游标
    cur=conn.cursor()

    cur.execute(“select * from user”)
    #取所有数据
    resTuple=cur.fetchall()
    print(type(resTuple))
    print (‘共%d条数据’%len(resTuple))

    cur.close()
    conn.commit()
    conn.close()
    print(‘sql执行成功’)


    注意:获取游标所在处开始及以下所有的数据,并以元组的形式返回,元组的每一个元素都也是一个由一行数据组成的元组,如果游标所在处没有数据,将返回空元组。执行完这个方法后,游标将移动到数据库表的最后

    更新数据

    代码示例:更新单条数据

    '''更新单条数据'''
    import pymysql
    #打开数据库连接
    conn=pymysql.connect('localhost','root','123456')
    conn.select_db('pythondb')
    #获取游标
    cur=conn.cursor()

    #更新一条数据
    update=cur.execute("update user set age=100 where name='kongsh'")
    print ('修改后受影响的行数为:',update)
    #查询一条数据
    cur.execute(select * from user where name="kongsh";')
    print(cur.fetchone())
    cur.close()
    conn.commit()
    conn.close()
    print('sql执行成功')

    代码示例:更新多条数据

    '''更新多条数据'''
    import pymysql
    #打开数据库连接
    conn=pymysql.connect('localhost','root','123456')
    conn.select_db('pythondb')
    #获取游标
    cur=conn.cursor()

    #更新前查询所有数据
    cur.execute("select * from user where name in ('kongsh','wen');")
    print('更新前的数据为:')
    for res in cur.fetchall():
    print (res)

    print ('*'*40)
    #更新2条数据
    sql="update user set age=%s where name=%s"
    update=cur.executemany(sql,[(15,'kongsh'),(18,'wen')])

    #更新2条数据后查询所有数据
    cur.execute("select * from user where name in ('kongsh','wen');")
    print('更新后的数据为:')
    for res in cur.fetchall():
    print (res)


    cur.close()
    conn.commit()
    conn.close()
    print('sql执行成功')


    删除数据

    代码示例:删除单条数据

    '''删除单条数据'''
    import pymysql
    #打开数据库连接
    conn=pymysql.connect('localhost','root','123456')
    conn.select_db('pythondb')
    #获取游标
    cur=conn.cursor()

    #删除前查询所有数据
    cur.execute("select * from user;")
    print('删除前的数据为:')
    for res in cur.fetchall():
    print (res)

    print ('*'*40)
    #删除1条数据
    cur.execute("delete from user where id=1")

    #删除后查询所有数据
    cur.execute("select * from user;")
    print('删除后的数据为:')
    for res in cur.fetchall():
    print (res)
    cur.close()
    conn.commit()
    conn.close()
    print('sql执行成功')

    代码示例:删除多条数据

    '''删除多条数据'''
    import pymysql
    #打开数据库连接
    conn=pymysql.connect('localhost','root','123456')
    conn.select_db('pythondb')
    #获取游标
    cur=conn.cursor()

    #删除前查询所有数据
    cur.execute("select * from user;")
    print('删除前的数据为:')
    for res in cur.fetchall():
    print (res)

    print ('*'*40)
    #删除2条数据
    sql="delete from user where id=%s"
    cur.executemany(sql,[(3),(4)])

    #删除后查询所有数据
    cur.execute("select * from user;")
    print('删除后的数据为:')
    for res in cur.fetchall():
    print (res)
    cur.close()
    conn.commit()
    conn.close()
    print('sql执行成功')


    事务回滚

    代码示例:’’‘事务回滚’’'

    import pymysql
    #打开数据库连接
    conn=pymysql.connect('localhost','root','123456')
    conn.select_db('pythondb')
    #获取游标
    cur=conn.cursor()

    #修改前查询所有数据
    cur.execute("select * from user;")
    print('修改前的数据为:')
    for res in cur.fetchall():
    print (res)

    print ('*'*40)
    #更新表中第1条数据
    cur.execute("update user set name='xiaoxiaoxiaoxiaoren' where id=5")

    #修改后查询所有数据
    cur.execute("select * from user;")
    print('修改后的数据为:')
    for res in cur.fetchall():
    print (res)
    print ('*'*40)
    #回滚事务
    conn.rollback()
    cur.execute("select * from user;")
    print('回滚事务后的数据为:')
    for res in cur.fetchall():
    print (res)

    cur.close()
    conn.commit()
    conn.close()
    print('sql执行成功')

    练习:插入100条数据到数据库

    代码示例:每次插入一条

    '''插入100条数据到数据库(每次插入一条)'''
    import pymysql
    import string,random
    #打开数据库连接
    conn=pymysql.connect('localhost','root','123456')
    conn.select_db('testdb')
    #获取游标
    cur=conn.cursor()

    #创建user表
    cur.execute('drop table if exists user')
    sql="""CREATE TABLE IF NOT EXISTS `user` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `name` varchar(255) NOT NULL,
    `age` int(11) NOT NULL,
    PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=0"""

    cur.execute(sql)

    #修改前查询所有数据
    cur.execute("select * from user;")
    print('修改前的数据为:')
    for res in cur.fetchall():
    print (res)

    print ('*'*40)
    #循环插入数据
    words=list(string.ascii_letters)
    sql="insert into user values(%s,%s,%s)"
    for i in range(100):
    random.shuffle(words)#打乱顺序
    cur.execute(sql,(i+1,"".join(words[:5]),random.randint(0,80)))

    #插入100条后查询所有数据
    cur.execute("select * from user;")
    print('修改后的数据为:')
    for res in cur.fetchall():
    print (res)
    print ('*'*40)

    cur.close()
    conn.commit()
    conn.close()
    print('sql执行成功')
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45

    代码示例:一次插入多条

    '''插入100条数据到数据库(一次插入多条)'''
    import pymysql
    import string,random
    #打开数据库连接
    conn=pymysql.connect('localhost','root','123456')
    conn.select_db('testdb')
    #获取游标
    cur=conn.cursor()

    #创建user表
    cur.execute('drop table if exists user')
    sql="""CREATE TABLE IF NOT EXISTS `user` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `name` varchar(255) NOT NULL,
    `age` int(11) NOT NULL,
    PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=0"""

    cur.execute(sql)

    #修改前查询所有数据
    cur.execute("select * from user;")
    print('修改前的数据为:')
    for res in cur.fetchall():
    print (res)

    print ('*'*40)
    #循环插入数据
    words=list(string.ascii_letters)
    sql="insert into user values(%s,%s,%s)"
    random.shuffle(words)#打乱顺序
    cur.executemany(sql,[(i+1,"".join(words[:5]),random.randint(0,80)) for i in range(100) ])

    #插入100条后查询所有数据
    cur.execute("select * from user;")
    print('修改后的数据为:')
    for res in cur.fetchall():
    print (res)
    print ('*'*40)

    cur.close()
    conn.commit()
    conn.close()
    print('sql执行成功')

    ————————————————

        https://blog.csdn.net/kongsuhongbaby/article/details/84948205


    版权声明:本文为CSDN博主「小小小小人ksh」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/kongsuhongbaby/article/details/84948205




    https://blog.csdn.net/kongsuhongbaby/article/details/84948205

    https://blog.csdn.net/kongsuhongbaby/article/details/84948205


  • 相关阅读:
    多态
    封装,继承,多态
    基本类型和引用类型的区别
    第七天 面向对象
    什么是Java线程池
    游戏内核架构
    放松
    静不下来心写代码
    速度和正确率
    理顺思路
  • 原文地址:https://www.cnblogs.com/xinxihua/p/14479741.html
Copyright © 2011-2022 走看看