#呼喚自我。_要查詢的查詢方法。
def執行(self,query,args=None):
““執行查詢
:param str query:要執行的查詢。
:param args:用於查詢的參數。(可選)
:類型參數:元組、列表或字典
:返回:受影響的行數
:rtype: int
如果args是列表或元組,則%s可以用作查詢中的占位符。
如果args是壹個字典,% s(name)可以用作查詢中的占位符。
"""
while self.nextset():
及格
query = self . mogrify(query,args)
結果=自己。_query(查詢)
自我。_executed =查詢
回送結果
# Call _do_get_result獲取查詢結果。
def _ query(self,q):
conn = self。_get_db()
自我。_last_executed = q
自我。_clear_result()
連接查詢(q)
自我。_do_get_result()
返回self.rowcount
#在此獲取結果
def _ do _ get _ result(self):
conn = self。_get_db()
自我。_result = result = conn._result
self . rowcount = result . affected _ rows
自我描述=結果描述
self . lastrowid = result . insert _ id
自我。_rows = result.rows
自我。_warnings_handled = False
如果不是自我。_延期_警告:
自我。_ show _ warnings()
事實上,這裏的代碼邏輯非常清晰。當調用cursor.execute執行SQL時,MySQL查詢的結果放在變量result中,這意味著結果集放在客戶端的內存變量中,因此獲取數據的方式是從該內存變量中獲取數據,但獲取數據的行為是不同的。
def fetch one(self):
“““獲取下壹行“““
自我。_check_executed()
如果自我。_rows為None或self.rownumber & gt= len(self_行):
不返回
結果=自己。_ rows【self . row number】
self.rownumber += 1
回送結果
def fetchmany(self,size=None):
“““獲取幾行“““
自我。_check_executed()
如果自我。_rows為無:
return()
end = self . row number+(size或self.arraysize)
結果=自己。_ rows【self . row number:end】
self . row number = min(end,len(self。_rows))
回送結果
def fetchall(self):
“““獲取所有行“““
自我。_check_executed()
如果自我。_rows為無:
return()
if self.rownumber:
結果=自己。_ rows【self . row number:】
否則:
結果=自己。_行
self . row number = len(self。_行)
回送結果
我嘴裏沒有證據。讓我們通過Wireshark抓取包來直接證明這壹點。首先,我如下所示在本地執行腳本,然後監視本地網卡流量。
導入pymysql
conn = pymysql . connect(host =‘XXX‘,port=3306,
用戶=‘xucl’,密碼=‘xucl xucl’,數據庫=‘xucl’)
cursor = conn.cursor()
cursor . execute(“select * from t“)
請註意,我沒有在這裏執行獲取操作。如果被監控的數據包包含結果,則證明我們之前的分析是正確的。話不多說,開始實驗。Wireshark抓取數據包的方式如下:
果然,這與我們之前的預測壹致。即使沒有fetch操作,MySQL也會將結果集發送給客戶端。此外,關於結果集的發送,請參考我的另壹篇文章:從盲SQL擴展。
結論:
當客戶端執行SQL時,MySQL會將結果集壹次性發送給客戶端。
收到結果集後,客戶端將其存儲在本地內存變量中。
Fetch結果只從這個局部變量中獲取,fetchone/fetchmany/fetchall只是在獲取行為上不合理,所以對於MySQL來說沒有什麽不合理的。