mysql--pymysql 模塊
阿新 • • 發佈:2019-01-19
mod ict pip connect cursor 輸入密碼 相對 字符串拼接 了解
一.pymysql模塊
1.安裝
pip3 install pymysql
2. 連接,執行slq,關閉(遊標)
import pymysql conn = pymysql.connect( host=‘127.0.0.1‘,#localhost port=3306, user=‘root‘, password=‘222‘, #字符串 database=‘shanku‘, charset=‘utf8‘ ) username = input(‘請輸入用戶名‘) pwd = input(‘請輸入密碼‘) # cursor = conn.cursor() #獲取元組類型數據的遊標 cursor = conn.cursor(pymysql.cursors.DictCursor) #獲取字典類型數據的遊標 # sql = ‘show databases;‘ # sql = ‘select * from student;‘ sql = ‘select * from student;‘ # sql = "select * from userinfo where username=‘%s‘ and password=‘%s‘;"%(username,pwd) res = cursor.execute(sql) #res受影響的行 # print(cursor.fetchall()) print(cursor.fetchone()) # cursor.scroll(2,‘absolute‘) cursor.scroll(1,‘relative‘) print(‘>>>>>‘,cursor.fetchone()) # print(‘>>>>>‘,cursor.fetchmany(1)) # print(res)
3.使用commit()
import pymysql conn = pymysql.connect( host=‘127.0.0.1‘,#localhost port=3306, user=‘root‘, password=‘222‘, #字符串 database=‘db1‘, charset=‘utf8‘ ) cursor = conn.cursor(pymysql.cursors.DictCursor) #獲取字典類型數據的遊標 sql = "insert into userinfo values(4,‘gaowang‘,666);" res = cursor.execute(sql) #res受影響的行 print(res) conn.commit() #凡是增刪改的操作都需要commit
4.遊標的移動
#我們可以再創建遊標的時候,在cursor裏面加上一個參數:cursor=conn.cursor(cursor=pymysql.cursors.DictCursor)獲取的結果就是字典格式的,fetchall或者fetchmany取出的結果是列表套字典的數據形式
這個取數據的操作就像讀取文件內容一樣,每次read之後,光標就移動到了對應的位置,我們可以通過seek來移動光標 同樣,我們可以移動遊標的位置,繼續取我們前面的數據,通過cursor.scroll(數字,模式),第一個參數就是一個int類型的數字,表示往後移動的記錄條數,第二個參數為移動的模式,有兩個值:absolute:絕對移動,relative:相對移動 #絕對移動:它是相對於所有數據的起始位置開始往後面移動的 #相對移動:他是相對於遊標的當前位置開始往後移動的 #絕對移動的演示 #print(cursor.fetchall()) #cursor.scroll(3,‘absolute‘) #從初始位置往後移動三條,那麽下次取出的數據為第四條數據 #print(cursor.fetchone()) #相對移動的演示 #print(cursor.fetchone()) #cursor.scroll(1,‘relative‘) #通過上面取了一次數據,遊標的位置在第二條的開頭,我現在相對移動了1個記錄,那麽下次再取,取出的是第三條,我相對於上一條,往下移動了一條 #print(cursor.fetchone())
二.execute()之sql註入
首先我們來寫一個簡單的登陸認證
import pymysql conn = pymysql.connect( host=‘127.0.0.1‘, port=3306, user=‘root‘, password=‘666‘, database=‘crm‘, charset=‘utf8‘ ) cursor = conn.cursor(pymysql.cursors.DictCursor) uname = input(‘請輸入用戶名:‘) pword = input(‘請輸入密碼:‘) sql = "select * from userinfo where username=‘%s‘ and password=‘%s‘;"%(uname,pword) res = cursor.execute(sql) #res我們說是得到的行數,如果這個行數不為零,說明用戶輸入的用戶名和密碼存在,如果為0說明存在 print(res) #如果輸入的用戶名和密碼錯誤,這個結果為0,如果正確,這個結果為1 if res: print(‘登陸成功‘) else: print(‘用戶名和密碼錯誤!‘) #通過上面的驗證方式,比我們使用文件來保存用戶名和密碼信息的來進行驗證操作要方便很多。
我們來看一個,直接連,不用知道用戶名和密碼,依然可以成功登陸的例子.如果在登陸時這樣輸入
第一種輸入方式:
asd‘ -- xx
這樣輸入的話等同於
select * from userinfo where username=‘asd‘ -- xxx‘ and password=‘‘;
第二種輸入方式:
請輸入用戶名:xxx‘ or 1=1 -- xxxxxx 請輸入密碼: select * from userinfo where username=‘xxx‘ or 1=1 -- xxxxxx‘ and password=‘‘; 登陸成功 我們只輸入了一個xxx‘ 加or 加 1=1 加 -- 加任意字符串 看上面被執行的sql語句你就發現了,or 後面跟了一個永遠為真的條件,那麽即便是username對不上,但是or後面的條件是成立的,也能夠登陸成功。
總結咱們剛才說的兩種sql註入的語句
#1、sql註入之:用戶存在,繞過密碼 asd‘ -- 任意字符 #2、sql註入之:用戶不存在,繞過用戶與密碼 xxx‘ or 1=1 -- 任意字符
為了解決這個問題,pymysql提供了excute()方法來幫我們拼接,並防止mysql註入
# 原來是我們對sql進行字符串拼接 # sql="select * from userinfo where name=‘%s‘ and password=‘%s‘" %(user,pwd) # print(sql) # res=cursor.execute(sql) #改寫為(execute幫我們做字符串拼接,我們無需且一定不能再為%s加引號了) sql="select * from userinfo where name=%s and password=%s" #!!!註意%s需要去掉引號,因為pymysql會自動為我們加上 res=cursor.execute(sql,[user,pwd]) #pymysql模塊自動幫我們解決sql註入的問題,只要我們按照pymysql的規矩來。
示例:
import pymysql conn = pymysql.connect( host=‘127.0.0.1‘,#localhost port=3306, user=‘root‘, password=‘222‘, #字符串 database=‘shanku‘, charset=‘utf8‘ ) username = input(‘請輸入用戶名‘) pwd = input(‘請輸入密碼‘) # cursor = conn.cursor() #獲取元組類型數據的遊標 cursor = conn.cursor(pymysql.cursors.DictCursor) #獲取字典類型數據的遊標 # sql = "select * from userinfo where username=‘%s‘ and password=‘%s‘;"%(username,pwd) sql = "select * from userinfo where username=%s and password=%s;" print(‘>>>>>‘,sql) res = cursor.execute(sql,[username,pwd]) #res受影響的行 print(res) if res: print(‘登錄成功‘) else: print(‘登錄失敗‘) # conn.commit()
三.增、刪、改:conn.commit()
import pymysql #鏈接 conn=pymysql.connect(host=‘localhost‘,port=‘3306‘,user=‘root‘,password=‘123‘,database=‘crm‘,charset=‘utf8‘) #遊標 cursor=conn.cursor() #執行sql語句 #part1 # sql=‘insert into userinfo(name,password) values("root","123456");‘ # res=cursor.execute(sql) #執行sql語句,返回sql影響成功的行數 # print(res) # print(cursor.lastrowid) #返回的是你插入的這條記錄是到了第幾條了 #part2 # sql=‘insert into userinfo(name,password) values(%s,%s);‘ # res=cursor.execute(sql,("root","123456")) #執行sql語句,返回sql影響成功的行數 # print(res) #還可以進行更改操作: #res=cursor.excute("update userinfo set username=‘taibaisb‘ where id=2") #print(res) #結果為1 #part3 sql=‘insert into userinfo(name,password) values(%s,%s);‘ res=cursor.executemany(sql,[("root","123456"),("lhf","12356"),("eee","156")]) #執行sql語句,返回sql影響成功的行數,一次插多條記錄 print(res) #上面的幾步,雖然都有返回結果,也就是那個受影響的函數res,但是你去數據庫裏面一看,並沒有保存到數據庫裏面, conn.commit() #必須執行conn.commit,註意是conn,不是cursor,執行這句提交後才發現表中插入記錄成功,沒有這句,上面的這幾步操作其實都沒有成功保存。 cursor.close() conn.close()
四 查:fetchone,fetchmany,fetchall
import pymysql #鏈接 conn=pymysql.connect(host=‘localhost‘,user=‘root‘,password=‘123‘,database=‘egon‘) #遊標 cursor=conn.cursor() #執行sql語句 sql=‘select * from userinfo;‘ rows=cursor.execute(sql) #執行sql語句,返回sql影響成功的行數rows,將結果放入一個集合,等待被查詢 # cursor.scroll(3,mode=‘absolute‘) # 相對絕對位置移動 # cursor.scroll(3,mode=‘relative‘) # 相對當前位置移動 res1=cursor.fetchone() res2=cursor.fetchone() res3=cursor.fetchone() res4=cursor.fetchmany(2) res5=cursor.fetchall() print(res1) print(res2) print(res3) print(res4) print(res5) print(‘%s rows in set (0.00 sec)‘ %rows) conn.commit() #提交後才發現表中插入記錄成功 cursor.close() conn.close()
五 獲取插入的最後一條數據的自增ID
mport pymysql conn=pymysql.connect(host=‘localhost‘,user=‘root‘,password=‘123‘,database=‘egon‘) cursor=conn.cursor() sql=‘insert into userinfo(name,password) values("xxx","123");‘ rows=cursor.execute(sql) print(cursor.lastrowid) #在插入語句後查看 conn.commit() cursor.close() conn.close()
mysql--pymysql 模塊