python連接操作mysql數據庫使用詳解

     在python3中,有個模塊pymysql,用戶可以通過這個模塊實現遠程對mysql數據庫的操作。

1.python操作mysql流程架構

2 .python操作mysql使用演示

1.安裝並且導入包pymysql,如果環境中沒有安裝pymysql包,可以直接pip3 install pymysql安裝該模塊,然後使用import pymysql查看是否安裝正確。下面是基於pycharm進行開發測試python連接操作數據庫

from pymysql import *

def main():
    # 創建Connection連接
    conn = connect(host='localhost',port=3306,database='jing_dong',user='root',password='123456',charset='utf8')
    # 獲得Cursor對象
    cs1 = conn.cursor()
    # 執行insert語句,並返回受影響的行數:添加一條數據
    # 增加
    count = cs1.execute('insert into goods_cates(name) values("硬盤")')
    #打印受影響的行數
    print(count)

    count = cs1.execute('insert into goods_cates(name) values("光盤")')
    print(count)

    # # 更新
    # count = cs1.execute('update goods_cates set name="機械硬盤" where name="硬盤"')
    # # 刪除
    # count = cs1.execute('delete from goods_cates where id=6')

    # 提交之前的操作,如果之前已經之執行過多次的execute,那麼就都進行提交
    conn.commit()

    # 關閉Cursor對象
    cs1.close()
    # 關閉Connection對象
    conn.close()

if __name__ == '__main__':
    main()

尖叫提示: 

1.Connection 對象

   1.1用於建立與數據庫的連接,創建對象:調用connect()方法,該方法有很多參數,可以參考源碼。

   1.2該connect()常用參數如下:這些參數的順序可以調整,不用一致。

  • 參數host:連接的mysql主機ip,如果本機是'localhost'
  • 參數port:連接的mysql主機的端口,默認是3306
  • 參數database:數據庫的名稱
  • 參數user:連接的用戶名
  • 參數password:連接的密碼
  • 參數charset:通信採用的編碼方式,推薦使用utf8

   1.3 Connection對象的方法

  • close()關閉連接
  • commit()提交,主要用來對數據增,刪,改操作後提交的。
  • cursor()返回Cursor對象,用於執行sql語句並獲得結果

2.Cursor對象

  • 用於執行sql語句,使用頻度最高的語句順序爲select、insert、update、delete
  • 獲取Cursor對象:調用Connection對象的cursor()方法

2.1對象的方法

  • close()關閉
  • execute(operation [, parameters ])執行語句,返回受影響的行數,主要用於執行insert、update、delete語句,也可以執行create、alter、drop等語句
  • fetchone()執行查詢語句時,獲取查詢結果集的第一個行數據,返回一個元組
  • fetchall()執行查詢時,獲取結果集的所有行,一行構成一個元組,再將這些元組裝入一個元組返回
  • fetchmany( int args )執行查詢時,獲取查詢結果集的指定幾行,返回一個元組。

2.2對象的屬性

  • rowcount只讀屬性,表示最近一次execute()執行後受影響的行數
  • connection獲得當前連接對象

3.python操作mysql的注意事項

1.如下通過python查詢mysql中多條數據

from pymysql import *

def main():
    # 創建Connection連接
    conn = connect(host='localhost',port=3306,user='root',password='123456',database='jing_dong',charset='utf8')
    # 獲得Cursor對象
    cs1 = conn.cursor()
    # 執行select語句,並返回受影響的行數:查詢一條數據
    count = cs1.execute('select id,name from goods where id>=4')
    # 打印受影響的行數
    print("查詢到%d條數據:" % count)

    # for i in range(count):
    #     # 獲取查詢的結果
    #     result = cs1.fetchone()
    #     # 打印查詢的結果
    #     print(result)
    #     # 獲取查詢的結果

    result = cs1.fetchall()
    print(result)

    # 關閉Cursor對象
    cs1.close()
    conn.close()

if __name__ == '__main__':
    main()
    
''''
查詢到19條數據:
((4, 'x550cc 15.6英寸筆記本'), (5, 'x240 超極本'), (6, 'u330p 13.3英寸超極本'), (7, 'svp13226scb 觸控超極本'), (8, 'ipad mini 7.9英寸平板電腦'), (9, 'ipad air 9.7英寸平板電腦'), (10, 'ipad mini 配備 retina 顯示屏'), (11, 'ideacentre c340 20英寸一體電腦 '), (12, 'vostro 3800-r1206 臺式電腦'), (13, 'imac me086ch/a 21.5英寸一體電腦'), (14, 'at7-7414lp 臺式電腦 linux )'), (15, 'z220sff f4f06pa工作站'), (16, 'poweredge ii服務器'), (17, 'mac pro專業級臺式電腦'), (18, 'hmz-t3w 頭戴顯示設備'), (19, '商務雙肩揹包'), (20, 'x3250 m4機架式服務器'), (21, '商務雙肩揹包'), (22, 'LaserJet Pro P1606dn 黑白激光打印機'))
Process finished with exit code 0

'''

2.如何防止sql注入 

下面演示什麼叫sql注入,就是非法的sql輸入來獲取系統的一些使用權限。

from pymysql import *

def main():

    find_name = input("請輸入物品名稱:")

    # 創建Connection連接
    conn = connect(host='localhost',port=3306,user='root',password='123456',database='jing_dong',charset='utf8')
    # 獲得Cursor對象
    cs1 = conn.cursor()

    # 輸入 " or 1=1 or "   (雙引號也要輸入)
    sql = 'select * from goods where name="%s"' % find_name
    print("""sql===>%s<====""" % sql)

    count = cs1.execute(sql)

    # 打印受影響的行數
    print(count)
    # 獲取查詢的結果
    # result = cs1.fetchone()
    result = cs1.fetchall()
    # 打印查詢的結果
    print(result)
    # 關閉Cursor對象
    cs1.close()
    # 關閉Connection對象
    conn.close()

if __name__ == '__main__':
    main()

執行上面程序,在輸入商品時,我們輸入" or 1=1 or "   (雙引號也要輸入),這樣與我們底層寫好的查詢語句進行拼接,如下,拼接後的sql就變成了select * from goods where name="" or 1=1 or "",這是一個恆成立的where子句,所以可以獲取該表中所有數據。

請輸入物品名稱:" or 1=1 or "
sql===>select * from goods where name="" or 1=1 or ""<====
22
((1, 'r510vc 15.6英寸筆記本', 5, 2, Decimal('3399.000'), b'\x01', b'\x00'), (2, 'y400n 14.0英寸筆記本電腦', 5, 7, Decimal('4999.000'), b'\x01', b'\x00'), (3, 'g150th 15.6英寸遊戲本', 4, 9, Decimal('8499.000'), b'\x01', b'\x00'), (4, 'x550cc 15.6英寸筆記本', 5, 2, Decimal('2799.000'), b'\x01', b'\x00'), (5, 'x240 超極本', 7, 7, Decimal('4880.000'), b'\x01', b'\x00'), (6, 'u330p 13.3英寸超極本', 7, 7, Decimal('4299.000'), b'\x01', b'\x00'), (7, 'svp13226scb 觸控超極本', 7, 6, Decimal('7999.000'), b'\x01', b'\x00'), (8, 'ipad mini 7.9英寸平板電腦', 2, 8, Decimal('1998.000'), b'\x01', b'\x00'), (9, 'ipad air 9.7英寸平板電腦', 2, 8, Decimal('3388.000'), b'\x01', b'\x00'), (10, 'ipad mini 配備 retina 顯示屏', 2, 8, Decimal('2788.000'), b'\x01', b'\x00'), (11, 'ideacentre c340 20英寸一體電腦 ', 1, 7, Decimal('3499.000'), b'\x01', b'\x00'), (12, 'vostro 3800-r1206 臺式電腦', 1, 5, Decimal('2899.000'), b'\x01', b'\x00'), (13, 'imac me086ch/a 21.5英寸一體電腦', 1, 8, Decimal('9188.000'), b'\x01', b'\x00'), (14, 'at7-7414lp 臺式電腦 linux )', 1, 3, Decimal('3699.000'), b'\x01', b'\x00'), (15, 'z220sff f4f06pa工作站', 3, 4, Decimal('4288.000'), b'\x01', b'\x00'), (16, 'poweredge ii服務器', 3, 5, Decimal('5388.000'), b'\x01', b'\x00'), (17, 'mac pro專業級臺式電腦', 3, 8, Decimal('28888.000'), b'\x01', b'\x00'), (18, 'hmz-t3w 頭戴顯示設備', 6, 6, Decimal('6999.000'), b'\x01', b'\x00'), (19, '商務雙肩揹包', 6, 6, Decimal('99.000'), b'\x01', b'\x00'), (20, 'x3250 m4機架式服務器', 3, 1, Decimal('6888.000'), b'\x01', b'\x00'), (21, '商務雙肩揹包', 6, 6, Decimal('99.000'), b'\x01', b'\x00'), (22, 'LaserJet Pro P1606dn 黑白激光打印機', 12, 4, Decimal('1849.000'), b'\x01', b'\x00'))

Process finished with exit code 0

當然,之所以有sql注入,還是我們在開發的時候相當於留下了“漏洞”,才讓別人有機可乘。比如python操作mysql,實際開發中我們不要寫這種拼接的形式,而是要將查詢語句參數化,就可以避免sql注入了。因爲execute(),實現了反sql注入功能。

from pymysql import *

def main():

    find_name = input("請輸入物品名稱:")

    # 創建Connection連接
    conn = connect(host='localhost',port=3306,user='root',password='123456',database='jing_dong',charset='utf8')
    # 獲得Cursor對象
    cs1 = conn.cursor()


    # 安全的方式
    # 構造參數列表
    params = [find_name]
    # 執行select語句,並返回受影響的行數:查詢所有數據
    count = cs1.execute('select * from goods where name=%s', params)
    # 注意:
    # 如果要是有多個參數,需要進行參數化
    # 那麼params = [數值1, 數值2....],此時sql語句中有多個%s即可

    # 打印受影響的行數
    print(count)
    # 獲取查詢的結果
    # result = cs1.fetchone()
    result = cs1.fetchall()
    # 打印查詢的結果
    print(result)
    # 關閉Cursor對象
    cs1.close()
    # 關閉Connection對象
    conn.close()

if __name__ == '__main__':
    main()

'''這個時候再用sql注入的方式進行sql注入,發現失敗了
請輸入物品名稱:" or 1=1 or "
0
()
'''
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章