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



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM