Python中操作mysql的pymysql模塊詳解
前言
pymsql是Python中操作MySQL的模塊,其使用方法和MySQLdb幾乎相同。但目前pymysql支持python3.x而后者不支持3.x版本。
本文測(cè)試python版本:2.7.11。mysql版本:5.6.24
一、安裝
pip3 install pymysql
二、使用操作
1、執(zhí)行SQL
#!/usr/bin/env pytho
# -*- coding:utf-8 -*-
import pymysql
# 創(chuàng)建連接
conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='', db='tkq1', charset='utf8')
# 創(chuàng)建游標(biāo)
cursor = conn.cursor()
# 執(zhí)行SQL,并返回收影響行數(shù)
effect_row = cursor.execute("select * from tb7")
# 執(zhí)行SQL,并返回受影響行數(shù)
#effect_row = cursor.execute("update tb7 set pass = '123' where nid = %s", (11,))
# 執(zhí)行SQL,并返回受影響行數(shù),執(zhí)行多次
#effect_row = cursor.executemany("insert into tb7(user,pass,licnese)values(%s,%s,%s)", [("u1","u1pass","11111"),("u2","u2pass","22222")])
# 提交,不然無(wú)法保存新建或者修改的數(shù)據(jù)
conn.commit()
# 關(guān)閉游標(biāo)
cursor.close()
# 關(guān)閉連接
conn.close()
注意:存在中文的時(shí)候,連接需要添加charset='utf8',否則中文顯示亂碼。
2、獲取查詢數(shù)據(jù)
#! /usr/bin/env python
# -*- coding:utf-8 -*-
# __author__ = "TKQ"
import pymysql
conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='', db='tkq1')
cursor = conn.cursor()
cursor.execute("select * from tb7")
# 獲取剩余結(jié)果的第一行數(shù)據(jù)
row_1 = cursor.fetchone()
print row_1
# 獲取剩余結(jié)果前n行數(shù)據(jù)
# row_2 = cursor.fetchmany(3)
# 獲取剩余結(jié)果所有數(shù)據(jù)
# row_3 = cursor.fetchall()
conn.commit()
cursor.close()
conn.close()
3、獲取新創(chuàng)建數(shù)據(jù)自增ID
可以獲取到最新自增的ID,也就是最后插入的一條數(shù)據(jù)ID
#! /usr/bin/env python
# -*- coding:utf-8 -*-
# __author__ = "TKQ"
import pymysql
conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='', db='tkq1')
cursor = conn.cursor()
effect_row = cursor.executemany("insert into tb7(user,pass,licnese)values(%s,%s,%s)", [("u3","u3pass","11113"),("u4","u4pass","22224")])
conn.commit()
cursor.close()
conn.close()
#獲取自增id
new_id = cursor.lastrowid
print new_id
4、移動(dòng)游標(biāo)
操作都是靠游標(biāo),那對(duì)游標(biāo)的控制也是必須的
注:在fetch數(shù)據(jù)時(shí)按照順序進(jìn)行,可以使用cursor.scroll(num,mode)來(lái)移動(dòng)游標(biāo)位置,如: cursor.scroll(1,mode='relative') # 相對(duì)當(dāng)前位置移動(dòng) cursor.scroll(2,mode='absolute') # 相對(duì)絕對(duì)位置移動(dòng)
5、fetch數(shù)據(jù)類型
關(guān)于默認(rèn)獲取的數(shù)據(jù)是元祖類型,如果想要或者字典類型的數(shù)據(jù),即:
#! /usr/bin/env python
# -*- coding:utf-8 -*-
# __author__ = "TKQ"
import pymysql
conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='', db='tkq1')
#游標(biāo)設(shè)置為字典類型
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
cursor.execute("select * from tb7")
row_1 = cursor.fetchone()
print row_1 #{u'licnese': 213, u'user': '123', u'nid': 10, u'pass': '213'}
conn.commit()
cursor.close()
conn.close()
6、調(diào)用存儲(chǔ)過(guò)程
a、調(diào)用無(wú)參存儲(chǔ)過(guò)程
#! /usr/bin/env python
# -*- coding:utf-8 -*-
# __author__ = "TKQ"
import pymysql
conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='', db='tkq1')
#游標(biāo)設(shè)置為字典類型
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
#無(wú)參數(shù)存儲(chǔ)過(guò)程
cursor.callproc('p2') #等價(jià)于cursor.execute("call p2()")
row_1 = cursor.fetchone()
print row_1
conn.commit()
cursor.close()
conn.close()
b、調(diào)用有參存儲(chǔ)過(guò)程
#! /usr/bin/env python
# -*- coding:utf-8 -*-
# __author__ = "TKQ"
import pymysql
conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='', db='tkq1')
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
cursor.callproc('p1', args=(1, 22, 3, 4))
#獲取執(zhí)行完存儲(chǔ)的參數(shù),參數(shù)@開(kāi)頭
cursor.execute("select @p1,@_p1_1,@_p1_2,@_p1_3") #{u'@_p1_1': 22, u'@p1': None, u'@_p1_2': 103, u'@_p1_3': 24}
row_1 = cursor.fetchone()
print row_1
conn.commit()
cursor.close()
conn.close()
三、關(guān)于pymysql防注入
1、字符串拼接查詢,造成注入
正常查詢語(yǔ)句:
#! /usr/bin/env python # -*- coding:utf-8 -*- # __author__ = "TKQ" import pymysql conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='', db='tkq1') cursor = conn.cursor() user="u1" passwd="u1pass" #正常構(gòu)造語(yǔ)句的情況 sql="select user,pass from tb7 where user='%s' and pass='%s'" % (user,passwd) #sql=select user,pass from tb7 where user='u1' and pass='u1pass' row_count=cursor.execute(sql) row_1 = cursor.fetchone() print row_count,row_1 conn.commit() cursor.close() conn.close()
構(gòu)造注入語(yǔ)句:
#! /usr/bin/env python # -*- coding:utf-8 -*- # __author__ = "TKQ" import pymysql conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='', db='tkq1') cursor = conn.cursor() user="u1' or '1'-- " passwd="u1pass" sql="select user,pass from tb7 where user='%s' and pass='%s'" % (user,passwd) #拼接語(yǔ)句被構(gòu)造成下面這樣,永真條件,此時(shí)就注入成功了。因此要避免這種情況需使用pymysql提供的參數(shù)化查詢。 #select user,pass from tb7 where user='u1' or '1'-- ' and pass='u1pass' row_count=cursor.execute(sql) row_1 = cursor.fetchone() print row_count,row_1 conn.commit() cursor.close() conn.close()
2、避免注入,使用pymysql提供的參數(shù)化語(yǔ)句
正常參數(shù)化查詢
#! /usr/bin/env python
# -*- coding:utf-8 -*-
# __author__ = "TKQ"
import pymysql
conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='', db='tkq1')
cursor = conn.cursor()
user="u1"
passwd="u1pass"
#執(zhí)行參數(shù)化查詢
row_count=cursor.execute("select user,pass from tb7 where user=%s and pass=%s",(user,passwd))
row_1 = cursor.fetchone()
print row_count,row_1
conn.commit()
cursor.close()
conn.close()
構(gòu)造注入,參數(shù)化查詢注入失敗。
#! /usr/bin/env python
# -*- coding:utf-8 -*-
# __author__ = "TKQ"
import pymysql
conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='', db='tkq1')
cursor = conn.cursor()
user="u1' or '1'-- "
passwd="u1pass"
#執(zhí)行參數(shù)化查詢
row_count=cursor.execute("select user,pass from tb7 where user=%s and pass=%s",(user,passwd))
#內(nèi)部執(zhí)行參數(shù)化生成的SQL語(yǔ)句,對(duì)特殊字符進(jìn)行了加\轉(zhuǎn)義,避免注入語(yǔ)句生成。
# sql=cursor.mogrify("select user,pass from tb7 where user=%s and pass=%s",(user,passwd))
# print sql
#select user,pass from tb7 where user='u1\' or \'1\'-- ' and pass='u1pass'被轉(zhuǎn)義的語(yǔ)句。
row_1 = cursor.fetchone()
print row_count,row_1
conn.commit()
cursor.close()
conn.close()
結(jié)論:excute執(zhí)行SQL語(yǔ)句的時(shí)候,必須使用參數(shù)化的方式,否則必然產(chǎn)生SQL注入漏洞。
3、使用存mysql儲(chǔ)過(guò)程動(dòng)態(tài)執(zhí)行SQL防注入
使用MYSQL存儲(chǔ)過(guò)程自動(dòng)提供防注入,動(dòng)態(tài)傳入SQL到存儲(chǔ)過(guò)程執(zhí)行語(yǔ)句。
delimiter \\
DROP PROCEDURE IF EXISTS proc_sql \\
CREATE PROCEDURE proc_sql (
in nid1 INT,
in nid2 INT,
in callsql VARCHAR(255)
)
BEGIN
set @nid1 = nid1;
set @nid2 = nid2;
set @callsql = callsql;
PREPARE myprod FROM @callsql;
-- PREPARE prod FROM 'select * from tb2 where nid>? and nid<?'; 傳入的值為字符串,?為占位符
-- 用@p1,和@p2填充占位符
EXECUTE myprod USING @nid1,@nid2;
DEALLOCATE prepare myprod;
END\\
delimiter ;
set @nid1=12; set @nid2=15; set @callsql = 'select * from tb7 where nid>? and nid<?'; CALL proc_sql(@nid1,@nid2,@callsql)
pymsql中調(diào)用
#! /usr/bin/env python
# -*- coding:utf-8 -*-
# __author__ = "TKQ"
import pymysql
conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='', db='tkq1')
cursor = conn.cursor()
mysql="select * from tb7 where nid>? and nid<?"
cursor.callproc('proc_sql', args=(11, 15, mysql))
rows = cursor.fetchall()
print rows #((12, 'u1', 'u1pass', 11111), (13, 'u2', 'u2pass', 22222), (14, 'u3', 'u3pass', 11113))
conn.commit()
cursor.close()
conn.close()
四、使用with簡(jiǎn)化連接過(guò)程
每次都連接關(guān)閉很麻煩,使用上下文管理,簡(jiǎn)化連接過(guò)程
#! /usr/bin/env python
# -*- coding:utf-8 -*-
# __author__ = "TKQ"
import pymysql
import contextlib
#定義上下文管理器,連接后自動(dòng)關(guān)閉連接
@contextlib.contextmanager
def mysql(host='127.0.0.1', port=3306, user='root', passwd='', db='tkq1',charset='utf8'):
conn = pymysql.connect(host=host, port=port, user=user, passwd=passwd, db=db, charset=charset)
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
try:
yield cursor
finally:
conn.commit()
cursor.close()
conn.close()
# 執(zhí)行sql
with mysql() as cursor:
print(cursor)
row_count = cursor.execute("select * from tb7")
row_1 = cursor.fetchone()
print row_count, row_1
總結(jié)
以上就是關(guān)于Python中pymysql模塊的全部?jī)?nèi)容,希望對(duì)大家學(xué)習(xí)或使用python能有一定的幫助,如果有疑問(wèn)大家可以留言交流。
- Python中模塊pymysql查詢結(jié)果后如何獲取字段列表
- Python中pymysql 模塊的使用詳解
- 使用python連接mysql數(shù)據(jù)庫(kù)之pymysql模塊的使用
- Python 中使用 PyMySQL模塊操作數(shù)據(jù)庫(kù)的方法
- python之pymysql模塊簡(jiǎn)單應(yīng)用示例代碼
- Python使用pymysql模塊操作mysql增刪改查實(shí)例分析
- Python 解析pymysql模塊操作數(shù)據(jù)庫(kù)的方法
- Python pymysql模塊安裝并操作過(guò)程解析
- python使用pymysql模塊操作MySQL
- Python中使用PyMySQL模塊的方法詳解
相關(guān)文章
Python?Flask框架實(shí)現(xiàn)Proteus仿真Arduino與網(wǎng)頁(yè)數(shù)據(jù)交互
這篇文章主要介紹了Python?Flask框架實(shí)現(xiàn)Proteus仿真Arduino與網(wǎng)頁(yè)數(shù)據(jù)交互,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧2022-11-11
python 自動(dòng)化將markdown文件轉(zhuǎn)成html文件的方法
這篇文章主要介紹了python 自動(dòng)化將markdown文件轉(zhuǎn)成html文件的方法的相關(guān)資料,本文介紹的非常詳細(xì),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-09-09
詳解python 破解網(wǎng)站反爬蟲(chóng)的兩種簡(jiǎn)單方法
這篇文章主要介紹了詳解python 破解網(wǎng)站反爬蟲(chóng)的兩種簡(jiǎn)單方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-02-02
python實(shí)現(xiàn)簡(jiǎn)單的超市商品銷售管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了python實(shí)現(xiàn)超市商品銷售管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-11-11
TF-IDF與余弦相似性的應(yīng)用(一) 自動(dòng)提取關(guān)鍵詞
這篇文章主要為大家詳細(xì)介紹了TF-IDF與余弦相似性的應(yīng)用,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-12-12
Windows下創(chuàng)建定時(shí)任務(wù)執(zhí)行Python腳本的方法實(shí)現(xiàn)
Python定時(shí)任務(wù)執(zhí)行,本文主要介紹了Windows下創(chuàng)建定時(shí)任務(wù)執(zhí)行Python腳本的方法實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下2023-11-11

