本節重點:python
以前咱們都是經過MySQL自帶的命令行客戶端工具mysql來操做數據庫,那如何在python程序中操做數據庫呢?這就用到了pymysql模塊,該模塊本質就是一個套接字客戶端軟件,使用前須要事先安裝。mysql
pip3 install pymysql
實現:使用Python實現用戶登陸,若是用戶存在則登陸成功(假設該用戶已在數據庫中)sql
import pymysql user = input('請輸入用戶名:').strip() pwd = input('請輸入密碼:').strip() # 1.鏈接 #建立一個鏈接對象<pymysql.connections.Connection object at 0x005F2910> conn = pymysql.connect(host='192.168.76.136', port=3306, user='root', password='root', db='db1', charset='utf8') # 2.建立遊標 #建立一個遊標對象<pymysql.cursors.Cursor object at 0x005E0290> cursor = conn.cursor() #注意%s須要加引號 sql = 'select * from user where username="%s" and password="%s"'%(user, pwd) print(sql) # 3.執行sql語句 result = cursor.execute(sql) #執行sql語句,返回sql查詢成功的記錄數目,不是查詢內容 print(result) # 4.關閉鏈接,遊標和鏈接都要關閉 cursor.close() conn.close() #打印結果時能夠根據判斷輸出不一樣結果 if result: print('登錄成功') else: print('登陸失敗') 或 print('登陸成功') if res else print('登陸失敗')
最後那一個空格,在一條sql語句中若是遇到select * from userinfo where username='user1' -- asadasdas' and pwd='' 則--以後的條件被註釋掉了(注意--後面還有一個空格)數據庫
#一、sql注入之:用戶存在,繞過密碼
user1' -- 任意字符工具
#二、sql注入之:用戶不存在,繞過用戶與密碼
xxx' or 1=1 -- 任意字符
fetch
解決方法: spa
# 原來是咱們對sql進行字符串拼接 # sql="select * from userinfo where name='%s' and password='%s'" %(username,pwd) # print(sql) # result=cursor.execute(sql) #改寫爲(execute幫咱們作字符串拼接,咱們無需且必定不能再爲%s加引號了) sql="select * from userinfo where name=%s and password=%s" #!!!注意%s須要去掉引號,由於pymysql會自動爲咱們加上 result=cursor.execute(sql,[user,pwd]) #pymysql模塊自動幫咱們解決sql注入的問題,只要咱們按照pymysql的規矩來。 sql = 'select * from user where username=%s and password=%s' res = cursor.execute(sql, (user, pwd))
commit()方法:在數據庫裏增、刪、改的時候,必需要進行提交,不然插入的數據不生效。命令行
import pymysql user = input('請輸入用戶名:').strip() pwd = input('請輸入密碼:').strip() conn = pymysql.connect(host='192.168.76.136', port=3306, user='root', password='root', db='db1', charset='utf8') cursor = conn.cursor()
#定義insert語句指針
sql_insert = 'insert into user (username, password) values (%s, %s)' res = cursor.execute(sql_insert, (user, pwd)) #必定要commit conn.commit() cursor.close() conn.close() print('登陸成功') if res else print('登陸失敗') mysql> select * from user; +----+----------+----------+----------------+ | id | username | password | emall | +----+----------+----------+----------------+ | 1 | user1 | 123 | user1@test.com | | 2 | user2 | 123 | user2@test.com | | 3 | user3 | 123 | NULL | +----+----------+----------+----------------+
#添加多條記錄,參數是一個列表中的多個集合code
res = cursor.executemany(sql_insert, [('aaa',123),('bbb',123)]) conn.commit() cursor.close() conn.close() mysql> select * from user; +----+----------+----------+----------------+ | id | username | password | emall | +----+----------+----------+----------------+ | 1 | user1 | 123 | user1@test.com | | 2 | user2 | 123 | user2@test.com | | 3 | user3 | 123 | NULL | | 4 | aaa | 123 | NULL | | 5 | bbb | 123 | NULL | +----+----------+----------+----------------+
#定義修改update語句
sql_update = 'update user set username = %s where id=2' res = cursor.execute(sql_update, user) conn.commit() cursor.close() conn.close() mysql> select * from user; +----+----------+----------+----------------+ | id | username | password | emall | +----+----------+----------+----------------+ | 1 | user1 | 123 | user1@test.com | | 2 | test1 | 123 | user2@test.com | | 3 | user3 | 123 | NULL | | 4 | aaa | 123 | NULL | | 5 | bbb | 123 | NULL | +----+----------+----------+----------------+
#定義刪除delete語句
sql_delete = 'delete from user where id=4' res = cursor.execute(sql_delete) conn.commit() cursor.close() conn.close() mysql> select * from user; +----+----------+----------+----------------+ | id | username | password | emall | +----+----------+----------+----------------+ | 1 | user1 | 123 | user1@test.com | | 2 | test1 | 123 | user2@test.com | | 3 | user3 | 123 | NULL | | 5 | bbb | 123 | NULL | +----+----------+----------+----------------+
fetchone():獲取下一行數據,第一次爲首行,可屢次執行。
fetchall():獲取全部行數據源
fetchmany(4):獲取4行數據,n可指定
查看錶內容:
一、fetchone()
import pymysql conn = pymysql.connect(host='192.168.76.136', port=3306, user='root', password='root', db='db1', charset='utf8') cursor = conn.cursor() #定義查詢語句 sql_select = 'select * from user ' res = cursor.execute(sql_select) row = cursor.fetchone() print(row) row = cursor.fetchone() print(row) cursor.close() conn.close() 結果:每執行一次查詢一行,可屢次執行逐行查看 (1, 'user1', 123, 'user1@test.com') (2, 'test1', 123, 'user2@test.com')
二、fetchmany(n)
row = cursor.fetchmany(3) print(row) 結果:顯示3條記錄 ((1, 'user1', 123, 'user1@test.com'), (2, 'test1', 123, 'user2@test.com'), (3, 'user3', 123, None))
三、cursor.fetchall()
row = cursor.fetchall() print(row) 結果:顯示全部記錄 ((1, 'user1', 123, 'user1@test.com'), (2, 'test1', 123, 'user2@test.com'), (3, 'user3', 123, None), (5, 'bbb', 123, None))
四、DictCursor
默認狀況下,咱們獲取到的返回值是元組,在獲取數據的時候並不方便,可使用如下方式來返回字典,每一行的數據都會生成一個字典: #在實例化conn的時候,將屬性cursor設置爲pymysql.cursors.DictCursor cursor = conn.cursor(cursor=pymysql.cursors.DictCursor) 結果: [{'id': 1, 'username': 'user1', 'password': 123, 'emall': 'user1@test.com'}, {'id': 2, 'username': 'test1', 'password': 123, 'emall': 'user2@test.com'}, {'id': 3, 'username': 'user3', 'password': 123, 'emall': None}, {'id': 5, 'username': 'bbb', 'password': 123, 'emall': None}]
五、指針位置移動
在fetchone示例中,在獲取行數據的時候,能夠理解開始的時候,有一個行指針指着第一行的上方,獲取一行,它就向下移動一行,因此當行指針到最後一行的時候,就不能再獲取到行的內容,因此咱們可使用以下方法來移動行指針: cursor.scroll(1,mode='relative') # 相對當前位置移動 cursor.scroll(2,mode='absolute') # 相對絕對位置移動 第一個值爲移動的行數,整數爲向下移動,負數爲向上移動,mode指定了是相對當前位置移動,仍是相對於首行移動 sql = 'select * from user' cursor.execute(sql) # 查詢第一行的數據 row = cursor.fetchone() print(row) # 查詢第二行數據 row = cursor.fetchone() print(row) cursor.scroll(-1,mode='relative') #設置以後,光標相對於當前位置(第3行)往前移動了一行,因此打印的結果爲第二行的數據 row = cursor.fetchone() print(row) cursor.scroll(0,mode='absolute') #設置以後,光標相對於首行沒有任何變化,因此打印的結果爲第一行數據 row = cursor.fetchone() print(row)