#呼喚自我。_要查詢的查詢方法。
def execute(self,query,args=None):
" " "執行查詢
:param str query:要執行的查詢。
:param args:用於查詢的參數。(可選)
:類型參數:元組、列表或字典
:return:受影響的行數
:rtype: int
如果args是列表或元組,則%s可以用作查詢中的占位符。
如果args是壹個字典,那麽可以在查詢中使用%(name)s作為占位符。
"""
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
自我。_清除_結果()
連接查詢(q)
自我。_do_get_result()
返回self.rowcount
#在此獲取結果
def _do_get_result(self):
conn = self。_get_db()
自我。_result =結果=連接. _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 fetchone(self):
"""獲取下壹行" " "
自我。_check_executed()
如果自我。_rows為None或self.rownumber & gt= len(自我。_行):
不返回
結果=自己。_rows[self.rownumber]
self.rownumber += 1
回送結果
def fetchmany(self,size=None):
"""獲取幾行" " "
自我。_check_executed()
如果自我。_rows為無:
return()
end = self.rownumber + (size或self.arraysize)
結果=自己。_rows[self.rownumber:end]
self.rownumber = min(end,len(self。_rows))
回送結果
def fetchall(self):
"""獲取所有行" " "
自我。_check_executed()
如果自我。_rows為無:
return()
if self.rownumber:
結果=自己。_rows[self.rownumber:]
否則:
結果=自己。_行
self.rownumber = len(self。_行)
回送結果
我嘴裏沒有證據。我們直接用Wireshark搶包來證明吧。首先,我如下所示在本地執行腳本,然後監視本地網卡流量。
導入pymysql
conn = pymysql.connect(host='xxx ',port=3306,
用戶='xucl ',密碼='xuclxucl ',數據庫='xucl ')
cursor = conn.cursor()
cursor.execute("select * from t ")
註意,我沒有在這裏執行獲取操作。如果被監控的數據包包含結果,就證明我們之前的分析是正確的。話不多說,開始實驗。Wireshark抓取數據包的方式如下:
果然和我們之前的預測壹致。即使沒有fetch操作,MySQL也會將結果集發送給客戶端。另外,關於結果集的發送,請參考我的另壹篇文章:從盲SQL擴展。
結論:
當客戶端執行SQL時,MySQL將結果集壹次性發送給客戶端。
收到結果集後,客戶機將其存儲在本地內存變量中。
Fetch結果只是從這個局部變量中獲取,fetchone/fetchmany/fetchall只是在獲取行為上不合理,所以對於MySQL來說沒有什麽不合理的。