python學習筆記 day45 pymysql
1. 使用pymysql模組實現python與資料庫的互動
需求: python實現使用者登入,使用者輸入使用者名稱和密碼,然後使用者資訊都儲存在userinfo資料庫中,可以藉助pymysql模組實現python和資料庫的互動,來模擬使用者登入~
首先我們先建立一個userinfo表:
在python中藉助pymysql模組(不推薦!!)
import pymysql usm=input("username:") pwd=input("password:") conn=pymysql.connect(host="localhost",user="root",password="******(你登入mysql的密碼)",database="db666") # connect()中的引數 host是哪一臺主機上安裝了mysql 接著是mysql登入的使用者名稱和密碼 以及所要操作連線的資料庫 cursor=conn.cursor() # 可以拿著cursor去操作執行資料庫中的語句 sql="select * from userinfo where username='%s' and password='%s'"%(usm,pwd) cursor.execute(sql) # 使用cursor.execute(sql)去執行sql語句----select * from userinfo where username= and password=result=cursor.fetchone() # 獲得查詢一條查詢結果,如果查到相應的資料,就會返回查到的結果給result(fetchone()只可以查到一條記錄) cursor.close() # 關閉資料庫 conn.close() print(result) # 會列印查詢的結果
執行結果:
上面在寫sql語句時採用了字串拼接的形式,一定要注意!!千萬不能這樣寫,因為:
就是因為上面sql語句使用了字串拼接的操作,專業術語叫做sql注入;
其實你會發現當輸入的使用者名稱為xuanxuna‘ -- 時 sql語句就相當於執行了 ’select * from userinfo where username="xuanxuan' --' and password='%s' " 顯然 password那部分使用--直接就註釋掉了!!
所以sql注入會有安全隱患!!
正確做法應該是,當所要執行的sql語句需要傳入引數時,我們應該在cursor.execute()中傳入相應的引數 來防止sql注入,pymysql會自動幫我們去執行相應的填充操作!!
import pymysql usm=input("username:") pwd=input("password:") conn=pymysql.connect(host="localhost",user="root",password="*******",database="db666") # 資料庫的連線 cursor=conn.cursor() sql="select * from userinfo where username=%s and password=%s" # 需要執行的sql語句,但是不能使用字串的拼接(sql注入很不安全(注意%s不加引號!!!) cursor.execute(sql,[usm,pwd]) # 將所要執行的sql語句中的引數 傳到cursor.execute()中來pymysql會自動填充執行(注意後面的需要填充的引數用列表或者元素的形式) # sql="select * from userinfo where username=%(u)s and password=%(p)s" # 下面cursor.execute(sql,{"u":usm,"p":pwd}) 就得寫成字典形式 # cursor.execute(sql,{"u":usm,"p":pwd}) result=cursor.fetchone() # select 資料庫查詢結果需要使用fetchone()來獲得; cursor.close() # 關閉資料庫 conn.close() # print(result) # 檢視操作資料庫(select查詢結果,如果使用者輸入的使用者名稱和密碼在userinfo表中可以查詢到,就證明該使用者是合法使用者,可以登入成功) if result: print("恭喜您,登陸成功") else: print("抱歉,登入失敗!")
執行結果:
2. 使用pymysql模組實現python操作資料庫---增刪改查
2.1 增
import pymysql conn=pymysql.connect(host="localhost",user="root",password="******",database="db666") cursor=conn.cursor() sql="insert into userinfo(username,password) values('xixi','123')" # 往infor表中增加一條記錄 cursor.execute(sql) # 使用cursor.execute()執行sql語句 conn.commit() # 將增加insert 資料項的操作提交!! 但是對資料庫查詢操作不需要提交 # cursor.fetchone() # 查詢操作需要獲得查詢結果的返回值(對資料庫增刪改時不需要cursor.fetchone()獲得一條記錄,只需要提交操作即可) cursor.close() # 關閉資料庫 conn.close()
執行結果:
增加資料的操作(帶有變數的,跟之前查詢帶有變數一樣,將需要傳入的引數放在cursor.execute(sql,[args])中去)不要sql注入;
import pymysql conn=pymysql.connect(host="localhost",user="root",password="*******",database="db666") cursor=conn.cursor() sql="insert into userinfo(username,password)values(%s,%s)" # 注意當使用cursor.execute(sql,(arg1,arg2))往sql中傳入引數時,一定要注意%s不要加引號!!! cursor.execute(sql,["dongdong","123"]) # cursor.execute()傳入引數可以寫成[] 或者()形式 conn.commit() cursor.close() conn.close()
執行結果:
當需要增加多條資料時:
import pymysql conn=pymysql.connect(host="localhost",user="root",password="******",database="db666") cursor=conn.cursor() sql="insert into userinfo(username,password) values(%s,%s)" # 當使用cursor.execute(sql,[arg1,arg2])傳入引數時 sql語句中響應變數的佔位符不要加引號!! cursor.executemany(sql,[['haha','123'],['nene','123'],['bobo','123']]) # 插入多條資料 要使用cursor.executemany(sql,[(),(),()]) 不是execute() 而是executemany()!!! conn.commit() # 當對資料庫執行增刪改操作時,一定要注意提交conn.commit() cursor.close() conn.close()
執行結果:
2.2 刪 改操作(同增)都需要在cursor.execute(sql)之後進行提交conn.commit()
3. 查--fetchone() 差一條資料,fetchmany(n) 查多條資料 fetchall()查所有資料;
import pymysql conn=pymysql.connect(host="localhost",user="root",password="******",database="db666") cursor=conn.cursor() sql="select * from userinfo" cursor.execute(sql) result=cursor.fetchone() # fetchone()獲得一條資料,查操作需要cursor.fetch() 但是不需要conn.commit() 增刪改剛好反過來 print(result) result=cursor.fetchone() # 又拿到一條資料(會有一個指標移動的,拿到下一條資料) print(result) cursor.close() conn.close()
執行結果:
其實可以看到的cursor.fetchone()返回的結果是一個元祖型別的,但是看起來很不方便,所以我們可以使用cursor=conn.cursor(cursor=pymysql.cursors,DictCursor)修改conn.cursor()的引數,使得cursor.fetchone()返回的結果是一個字典(欄位:欄位對應的值)
import pymysql conn=pymysql.connect(host="localhost",user="root",password="******",database="db666") cursor=conn.cursor(cursor=pymysql.cursors.DictCursor) # 修改conn.cursor(cursor=)的引數,使得cursor.fetchone()返回的結果不再是元組 而是直觀的字典形式 sql="select * from userinfo" cursor.execute(sql) result=cursor.fetchone() # fetchone()獲得一條資料,查操作需要cursor.fetch() 但是不需要conn.commit() 增刪改剛好反過來 print(result) result=cursor.fetchone() # 又拿到一條資料(會有一個指標移動的,拿到下一條資料) print(result) cursor.close() conn.close()
執行結果:
如果是獲得多條資料時:可以使用cursor.fetchmany(n) 獲得所有資料可以使用cursor.fetchall()
import pymysql conn=pymysql.connect(host="localhost",user="root",password="******",database="db666") cursor=conn.cursor(cursor=pymysql.cursors.DictCursor) # 修改conn.cursor(cursor=)的引數,使得cursor.fetchone()返回的結果不再是元組 而是直觀的字典形式 sql="select * from userinfo" cursor.execute(sql) result=cursor.fetchmany(4) # fetchmany(4)獲得查詢結果的四條 print(result) cursor.close() conn.close()
執行結果:
import pymysql conn=pymysql.connect(host="localhost",user="root",password="***********",database="db666") cursor=conn.cursor(cursor=pymysql.cursors.DictCursor) # 修改conn.cursor(cursor=)的引數,使得cursor.fetchone()返回的結果不再是元組 而是直觀的字典形式 sql="select * from userinfo" cursor.execute(sql) result=cursor.fetchall() # fetchall()獲得所有的查詢結果 print(result) cursor.close() conn.close()
4. 獲得新插入資料的自增ID(cursor.lastrowid)
就是當一張表插入資料的欄位比如userinfo表 只插入username,password 但是可能有時候需要獲得新插入資料的uid(主鍵自增的id) 就需要使用cursor.lastrowid獲得
import pymysql conn=pymysql.connect(host="localhost",user="root",password="123",database="db666") cursor=conn.cursor() # cursor=conn.cursor(cursor=pymysql.cursors.DictCursor)顯示結果是字典形式 一般select查詢時才會用到 sql="insert into userinfo(username,password) values(%s,%s)" cursor.execute(sql,["nono","124"]) conn.commit() # 對資料庫執行增刪改時需要提交 print(cursor.lastrowid) # 獲得最新插入資料的自增ID cursor.close() conn.close()
執行結果: