1. PyMySQL模組介紹
1.1 什麼是DB-API
Python標準資料庫規範為 DB-API, DB-API定義了一系列必須的物件和資料庫操作方式,以便為各種資料庫系統和資料庫訪問程式提供一致的訪問介面。
1.2 資料庫操作模組
DB-API介面封裝成資料庫操作模組,PyMySQL是python操作MySQL資料庫的一種模組。
PyMySQL官網
https://pypi.org/project/PyMySQL/
2. PyMySQL安裝
PyMySQL不是從官網安裝,python直譯器的安裝路徑已經被新增到系統環境變數,直接在全域性pip install PyMySQL即可
3. PyMySQL使用
3.1 操作前準備
import pymysql
from pymysql.cursors import DictCursor, Cursor
# 建立資料庫連線
conn_obj = pymysql.connect(
user='root',
password='123456789',
database='test01', # 資料庫名稱
host='127.0.0.1',
port=3306,
charset='utf8mb4', # 資料庫的編碼格式
cursorclass=DictCursor # DictCursor返回的資料是字典型別(帶有列名),Cursor返回的資料是元組型別(不帶列名)
)
# 產生遊標物件
cursor_obj = conn_obj.cursor()
3.2 查詢資料
[1]查詢所有資料 fetchall
DictCursor返回的資料是字典型別
sql = "select * from dep;" # SQL語句會被高亮顯示
cursor_obj.execute(sql) # 執行SQL語句
result = cursor_obj.fetchall()
print(result)
[2]查詢一條資料 fetchone
每一個fetchone只獲取一條資料,下一個fetchone基於上一個fetchone向後獲取
sql = "select * from dep;" # SQL語句會被高亮顯示
cursor_obj.execute(sql) # 執行SQL語句
result = cursor_obj.fetchone()
print(result)
result2 = cursor_obj.fetchone() # 基於上一個fetchone向後獲取
print(result2)
[3]查詢指定條數資料 fetchmany
sql = "select * from dep;" # SQL語句會被高亮顯示
cursor_obj.execute(sql) # 執行SQL語句
result = cursor_obj.fetchmany() # 預設獲取1條資料
print(result)
result2 = cursor_obj.fetchmany(2) # 獲取指定條數2條
print(result2)
[4]移動游標 scroll
cursor_obj.scroll(value, mode)
value---移動位置的數量
mode---relative:相對位置移動,absolute:以開頭為基準絕對位置移動
relative應用:
sql = "select * from dep;" # SQL語句會被高亮顯示
cursor_obj.execute(sql) # 執行SQL語句
res1 = cursor_obj.fetchone()
print(res1)
cursor_obj.scroll(1, 'relative') # 游標向後移動了1個位置
res2 = cursor_obj.fetchone()
print(res2)
absolute應用:
sql = "select * from dep;" # SQL語句會被高亮顯示
cursor_obj.execute(sql) # 執行SQL語句
res1 = cursor_obj.fetchone()
print(res1)
cursor_obj.scroll(0, 'absolute') # 相對於開頭移動了0個位置
res2 = cursor_obj.fetchone()
print(res2)
cursor_obj.scroll(1, 'absolute') # 相對於開頭移動了1個位置
res3 = cursor_obj.fetchone()
print(res3)
3.3 插入資料
[1]表結構
[2]嘗試插入資料
sql = "insert into dep(name) values ('電腦')"
cursor_obj.execute(sql) # 執行該sql語句之後在資料庫中並沒有插入資料
[3]需要commit提交事務才能成功插入資料
sql = "insert into dep(name) values ('電腦')"
cursor_obj.execute(sql)
conn_obj.commit()
由於步驟3是在pycharm中在步驟2的基礎上新增一行程式碼實現,快取存在,所以步驟3的id是在快取的基礎上增加
手動conn_obj.commit( )的效果與connect( )的預設引數autocommit=False改為True一致,二選一即可
[4]插入字串型別,一定要給值的中括號加引號' '
字串型別{ }不加引號會報錯
value1 = 205
value2 = '電腦'
sql = f"insert into dep(id, name) values({value1}, {value2})"
cursor_obj.execute(sql)
conn_obj.commit()
字串型別{ }加上引號正常插入資料
value1 = 205
value2 = '電腦'
sql = f"insert into dep(id, name) values({value1}, '{value2}')"
cursor_obj.execute(sql)
conn_obj.commit()
[5]為了解決步驟4給字串型別{ }加引號問題,pymysql提供了sql的格式化輸出語法
執行sql語句關鍵字execute的解釋
def execute(self, query, args=None):
:param query: Query to execute. query為需要執行的sql語句,字串型別
:type query: str
:param args: Parameters used with query. (optional) args可以是元組、列表、字典
:type args: tuple, list or dict
If args is a list or tuple, %s can be used as a placeholder in the query.
如果args是列表或元組,%s可以被用於佔位 按位置傳參
If args is a dict, %(key)s can be used as a placeholder in the query.
如果args是字典,則%(key)s可以用作查詢中的佔位符。 按關鍵字傳參
方法一:按位置傳入引數
value1 = 207
value2 = 'internet'
sql = f"insert into dep(id, name) values(%s, %s)"
cursor_obj.execute(sql, [value1, value2])
conn_obj.commit()
轉換說明符 解釋
%d、%i 轉換為帶符號的十進位制數
%o 轉換為帶符號的八進位制數
%x、%X 轉換為帶符號的十六進位制數
%e 轉化為科學計數法表示的浮點數(e 小寫)
%E 轉化為科學計數法表示的浮點數(E 小寫)
%f、%F 轉化為十進位制浮點數
%g 智慧選擇使用 %f 或 %e 格式
%G 智慧選擇使用 %F 或 %E 格式
%c 格式化字元及其ASCII碼
%r 使用 repr() 函式將表示式轉換為字串
%s 使用 str() 函式將表示式轉換為字串
通常使用%s也能將python的int型別轉換為MySQL中的int型別
方法二:按關鍵字傳入引數
sql = f"insert into dep(id, name) values(%(v1)s, %(v2)s)"
cursor_obj.execute(sql, {'v1': 208, 'v2': 'develop'})
conn_obj.commit()
3.4 更新資料
sql = "update dep set name='research' where name='develop'"
cursor_obj.execute(sql)
conn_obj.commit()
3.5 刪除資料
sql = "delete from dep where id=207"
cursor_obj.execute(sql)
conn_obj.commit()
3.6 使用executemany一次插入多條資料
[1]按位置傳入
sql = "insert into dep(id, name) values(%s, %s);"
cursor_obj.executemany(sql, [(212, 'd'), (213, 'e'), (214, 'f')])
conn_obj.commit()
[2]按關鍵字傳入
sql = "insert into dep(id, name) values(%(v1)s, %(v2)s);"
cursor_obj.executemany(sql, [{'v1': 215, 'v2': 'g'}, {'v1': 216, 'v2': 'h'}, {'v1': 217, 'v2': 'i'}])
conn_obj.commit()
3.7 SQL隱碼攻擊問題
[1]字串格式化輸出+引號進行佔位傳值
模擬登入:輸入使用者名稱和密碼
login_name = input('請輸入使用者名稱:')
login_pwd = input('請輸入密碼:')
sql = f"select * from info where username='{login_name}' and password='{login_pwd}';"
print(f'sql語句為{sql}')
cursor_obj.execute(sql)
res = cursor_obj.fetchall()
print(res)
if res:
print('登入成功')
else:
print('登入失敗')
[2]正常輸入使用者名稱密碼進行登入
[3]SQL隱碼攻擊問題:-- 空格後面的內容全部為註釋內容
輸入使用者名稱時在使用者名稱後面加上-- ,--後面的內容全部變成了註釋,導致sql語句失效
[4]解決SQL隱碼攻擊問題的本質是處理特殊符號
execute方法自帶校驗SQL隱碼攻擊問題,自動處理特殊符號
login_name = input('請輸入使用者名稱:')
login_pwd = input('請輸入密碼:')
sql = f"select * from info where username=%s and password=%s;"
print(f'sql語句為{sql}')
cursor_obj.execute(sql, (login_name, login_pwd))
res = cursor_obj.fetchall()
print(res)
if res:
print('登入成功')
else:
print('登入失敗')