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