pymysql模块和SQL注入
目錄
1.sql復習和分表操作
2.pymysql模塊
2.1 pymysql的使用步驟
2.1 pymysql 增刪改
1.數據提交和數據回滾
3.sql注入
1. 什么是SQL注入
2.非安全方式的SQL語句
3.安全方式的SQL語句
1.sql復習和分表操作
# 創建數據庫 create database if not exists jing_dong charset = utf8; # 切換數據庫 use jing_dong; # 創建表 create table goods (id int unsigned primary key auto_increment not null,name varchar(150) not null,cate_name varchar(40) not null,brand_name varchar(40) not null,price decimal(10, 3) not null default 0,is_show bit not null default 1,is_saleoff bit not null default 0 );# 插入數據 insert into goods values (0, 'r510vc 15.6英寸筆記本', '筆記本', '華碩', '3399', default, default); insert into goods values (0, 'y400n 14.0英寸筆記本電腦', '筆記本', '聯想', '4999', default, default); insert into goods values (0, 'g150th 15.6英寸游戲本', '游戲本', '雷神', '8499', default, default); insert into goods values (0, 'x550cc 15.6英寸筆記本', '筆記本', '華碩', '2799', default, default); insert into goods values (0, 'x240 超極本', '超級本', '聯想', '4880', default, default); insert into goods values (0, 'u330p 13.3英寸超極本', '超級本', '聯想', '4299', default, default); insert into goods values (0, 'svp13226scb 觸控超極本', '超級本', '索尼', '7999', default, default); insert into goods values (0, 'ipad mini 7.9英寸平板電腦', '平板電腦', '蘋果', '1998', default, default); insert into goods values (0, 'ipad air 9.7英寸平板電腦', '平板電腦', '蘋果', '3388', default, default); insert into goods values (0, 'ipad mini 配備 retina 顯示屏', '平板電腦', '蘋果', '2788', default, default); insert into goods values (0, 'ideacentre c340 20英寸一體電腦 ', '臺式機', '聯想', '3499', default, default); insert into goods values (0, 'vostro 3800-r1206 臺式電腦', '臺式機', '戴爾', '2899', default, default); insert into goods values (0, 'imac me086ch/a 21.5英寸一體電腦', '臺式機', '蘋果', '9188', default, default); insert into goods values (0, 'at7-7414lp 臺式電腦 linux )', '臺式機', '宏碁', '3699', default, default); insert into goods values (0, 'z220sff f4f06pa工作站', '服務器/工作站', '惠普', '4288', default, default); insert into goods values (0, 'poweredge ii服務器', '服務器/工作站', '戴爾', '5388', default, default); insert into goods values (0, 'mac pro專業級臺式電腦', '服務器/工作站', '蘋果', '28888', default, default); insert into goods values (0, 'hmz-t3w 頭戴顯示設備', '筆記本配件', '索尼', '6999', default, default); insert into goods values (0, '商務雙肩背包', '筆記本配件', '索尼', '99', default, default); insert into goods values (0, 'x3250 m4機架式服務器', '服務器/工作站', 'ibm', '6888', default, default); insert into goods values (0, '商務雙肩背包', '筆記本配件', '索尼', '99', default, default);# 1.查詢類型cate_name為 '超極本' 的商品名稱、價格 select name, price from goods where cate_name = '超級本'; #2. 顯示商品的種類 select cate_name from goods group by cate_name; # distinct可以去重 select distinct cate_name from goods; # 3.求所有電腦產品的平均價格,并且保留兩位小數 select round(avg(price), 2) from goods; # 4. 顯示每種商品的平均價格 select cate_name, round(avg(price), 2) as avg from goods group by cate_name; # 5. 查詢每種類型的商品中 最貴、最便宜、平均價、數量 select cate_name, max(price), min(price), avg(price), count(*) from goods group by cate_name; # 6.查詢所有價格大于平均價格的商品,并且按價格降序排序 select * from goods where price > (select avg(price) from goods) order by price desc;# 創建商品分類表,用于存儲所有的商品分類 create table if not exists goods_cates (id int unsigned primary key auto_increment,name varchar(100) ); # 將商品表中存在的商品分類的名字 寫入到 商品分類表 # 1. 得知道現在在商品表中都有哪些商品分類 select cate_name from goods group by cate_name; insert into goods_cates(name) values ('筆記本'),('游戲本');# 新的語法,在將查詢結果 插入到表中 insert into 表名 select .... insert into goods_cates(name) select cate_name from goods group by cate_name;select * from goods_cates;# 2. 將goods表中的 cate_name 都修改為 goods_cate中的id的值 update goods as g join goods_cates as gc on g.cate_name = gc.name set g.cate_name=gc.id;# update .... set... 更新數據的語法 # goods join goods_cates 連表查詢。 條件 g.cate_name = gc.name # set 后面的 設置更新的數據, 將 g.cate_name=gc.id# 3. 將cate_name 字段名 修改為 cate_id alter table goods change cate_name cate_id int unsigned;# 獲取一下 商品的品牌名稱 select brand_name from goods group by brand_name;# 將goods表中的 brand_name 放到 商品品牌表 goods_brands # 創建表的同時插入數據。 create table xxx() ...select ...... # 在創建表的同時 將 select查詢到的數據 插入到創建的表當中。 create table goods_brands(id int unsigned primary key auto_increment,name varchar(100) ) select brand_name as name from goods group by brand_name; # 注意點,使用 create table xxx() ...select ...... 插入數據的時候, # select 后面的字段 要和 創建的表中的字段名一致,一致的時候,才會將數據插入到指定的字段中 # 如果字段不一致,會在表中創建一個新的列,存儲查詢出來的數據 # drop table goods_brands;# 2. 將goods表中的brand_name 改為 goods_brands表中 id update goods g join goods_brands gb on g.brand_name = gb.name set g.brand_name=gb.id;# 3. 修改表結構, 將 goods表中的 brand_name 改為 brand_id alter table goods change brand_name brand_id int unsigned;2.pymysql模塊
幫助我們在python代碼中去對mysql數據庫中的數據實現增刪改查操作。
2.1 pymysql的使用步驟
? ? ? ??
-
導包
-
創建連接對象(建立和mysql數據庫服務的連接)
-
創建一個游標對象(這個游標對象就是專門去執行sql語句的對象)
-
使用游標對象執行sql語句(增刪改查)
-
關閉游標對象
-
關閉連接對象
pysql查詢
# 導包 from pymysql import connect # 創建連接對象 conn = connect(host='127.0.0.1',port=3306,database='jing_dong',user='root',password='123456',charset='utf8') # 創建游標對象 cur = conn.cursor()# 執行sql # 調用execute 返回值是在執行這條sql時受影響的行數。 num = cur.execute('select * from goods where price > 3000 ') # print(num) # print(cur.fetchmany(5)) fetchmany 返回指定條數的數據 # print(cur.fetchall()) fetchall 返回查詢的所有結果,返回一個元組 # print(cur.fetchone()) fetchone 獲取的是查詢結果的的單個數據 返回一個元組,元組中的元素就是這條數據的列值 res =cur.fetchone() print(res) # 關閉游標對象和連接對象 cur.close() conn.close()2.1 pymysql 增刪改
1.數據提交和數據回滾
- 數據提交commit
數據庫中的基本操作: 增刪改查. 上一個章節中我們知道如何完成對數據庫中數據的獲取其實也就是查, 比如獲取一條數據或者獲取所有數據等.?
注意:查數據, 并不會對原有數據庫中的數據造成影響. 而增刪改這三個操作都會對原有數據庫中的數據造成影響. 也就說查數據不會修改原有數據空中的數據, 而增刪改會修改原有數據庫中的數據.
當對原有數據庫中數據有修改時需要使用:
# commit()提交數據到數據庫 # 這里可以理解為 數據庫詢問是否確定修改數據 然后commit()就是確定修改的意思 conn.commit()- 數據回滾rollback()
當我們在使用pymysql對數據進行響應的操作時, 會有可能會有一些錯誤操作, 這是如果想要數據返回到最原始的狀態可以使用數據回滾操作
注意:數據回滾是需要在 commit() 之前才有效的, 也就是說數據還沒有確定修改這時候使用數據回滾才是有效的
# 回滾數據到什么都沒做的原始狀態 即撤銷剛剛所有的修改操作 conn.rollback()說白了,就是修改數據的時候,數據不會立即保持到mysql服務器中,而是在緩存中。commit就是確認將緩存中修改的數據保持到mysql服務器中,rollback就是撤銷修改。
2.pymysql的增刪改操作
# 演示pymysql的增刪改操作 import pymysql# 創建連接對象 conn = pymysql.connect(host='127.0.0.1',port=3306,user='root',password='mysql',charset='utf8' )# 連接數據庫的時候 可以去指定要操作的數據庫名字。 切換數據庫: use 數據庫名; conn.select_db('jing_dong')# 創建游標對象 cursor = conn.cursor()# sql_str = "show tables;" # cursor.execute(sql_str)# 1. 增加數據 # sql_str = "insert into test(name) values('小明');" # cursor.execute(sql_str)# 2. 刪除數據 # sql_str = 'delete from test where id=1;' # cursor.execute(sql_str)# 3. 修改數據 sql_str = "update test set name='小明明' where id=5;" cursor.execute(sql_str)# 在使用pymysql對數據進行增刪改操作的時候,需要我們手動的提交事務、 conn.commit()# 獲取執行結果 # print(cursor.fetchall())cursor.close() conn.close()# 在使用pymysql進行對數據的 增刪改的時候,操作完畢之后,記得 使用連接對象.commit() 對操作的數據進行提交之后才會在表中生效3.sql注入
1. 什么是SQL注入
-
SQL注入:
簡單說sql注入是一種可以使得數據庫中的數據泄露的方式. 如果有一些人有惡意的目的, 可以利用sql注入完成盜取數據.
-
產生原因:
后臺將用戶提交的帶有惡意的數據和SQL進行字符串方式的拼接,從而影響了SQL語句的語義,最終產生數據泄露的現象.
? ? ? ? ? ? ? ?簡單的說, 就是利用各種方式提交數據給程序并讓這些數據和SQL語句產生結合, 進而讓新產生的SQL語句和之前的原始的SQL語句變成不同的意思, 至此就可以利用新產生的SQL語句獲取想要的數據了.
-
防止SQL注入
SQL語句的參數化可以防止SQL注入的產生. 將SQL語句的所有數據參數存在一個列表中傳遞給execute函數的第二個參數進行執行, 就是SQL語句參數化.
2.非安全方式的SQL語句
from pymysql import connect# 創建Connection連接 conn = connect(host='localhost', port=3306, user='root', password='mysql', database='jing_dong', charset='utf8')# 獲得Cursor對象 cur = conn.cursor()# 獲取用戶想要查詢的物品名稱 find_name = input("請輸入物品名稱:")# 非安全方式的sql語句 sql = 'select * from goods where name="%s"' % find_name# 執行sql語句 count = cur.execute(sql)# 獲取查詢的結果 result = cur.fetchall()# 打印查詢的結果 print(result)# 關閉Cursor對象 cur.close()# 關閉Connection對象 conn.close()注意:
在輸入商品名稱的時候,輸入
# 雙引號也要輸入 " or 1=1 or "這樣就完成了一個簡單的注入
# 原始的sql語句 sql = 'select * from goods where name="%s"' % find_name # 輸入 " or 1=1 or " 后的sql語句 sql = 'select * from goods where name="" or 1=1 or ""'這里?name= "" or 1=1 or ""?這個條件是一定成立的,因為or是或的意思多個條件只要有一個條件成立整體就成立,而1=1是一定成立的. 這就造成這個sql語句的意思發生里改變.
3.安全方式的SQL語句
from pymysql import connect# 創建Connection連接 conn = connect(host='localhost', port=3306, user='root', password='mysql', database='jing_dong', charset='utf8')# 獲得Cursor對象 cur = conn.cursor()# 獲取用戶想要查詢的物品名稱 find_name = input("請輸入物品名稱:")# sql語句 # 注意: # 此處不同于python的字符串格式化,必須全部使用%s占位 # 所有參數所需占位符外不需要加引號 sql = 'select * from goods where name=%s;'# 安全的方式 # 構造參數列表 params = [find_name] # 執行select語句 # 注意: # 如果要是有多個參數,需要進行參數化 # 那么params = [數值1, 數值2....],此時sql語句中有多個%s即可 count = cur.execute(sql, params)# 獲取查詢的結果 result = cur.fetchall()# 打印查詢的結果 print(result)# 關閉Cursor對象 cur.close()# 關閉Connection對象 conn.close()如果構建的不是參數列表,而是一個字典,那么占位符%s,改成 %()s? 括號里面寫入字典的鍵
如下:
her = input('請輸入:') her_dicr = {'name':her} sql = 'select * from hero where hname=%(name)s'count = cur.execute(sql,her_dicr)利用參數化列表就可以完成防止SQL注入
總結
以上是生活随笔為你收集整理的pymysql模块和SQL注入的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 免费的瑞星2008杀毒软件!
- 下一篇: 11_mysql与Python交互_1