使用pyMySQL連線資料庫時遇到的幾個問題
阿新 • • 發佈:2019-02-15
最近幾天在折騰MySQL,遇到幾個問題,整理一下,環境為python3.4,沒有mysqldb,只好用pymysql。
1、使用with pymysql.connect() 語句時,返回的物件是cursor型別,不是connection型別,需要注意一下。
2、想要實現向資料庫中新增記錄時記錄已存在則更新記錄的功能,一開始考慮用on duplicate key update語句,但這樣產生了一個新的問題,就是這樣會導致自增長的主鍵不連續。產生的原因是因為表鎖的機制問題。因為在執行該語句前無法確定是否需要插入新行。這種情況下MySQL預設的做法是先申請一個位置,若是執行insert操作的話就不會有問題,若執行update操作則這個位置就空下了,由此導致自增欄位不連續。
有一種解決方法是設定innodb_autoinc_lock_mode=0,但這樣可能會在併發插入時出現問題,雖然我的小資料庫只有自己在用,為了學習起見還是換個方法……更詳細的解釋看這裡
3、為了讓自增長欄位連續,最好採用simple insert的方式插入,因此需要用到儲存過程來對記錄是否存在做判定。
with pymysql.connect(**self.login) as cursor: info = self.recentMatch() for i in info: arg = (ins[0], ins[1], ins[2]) cursor.callproc('updaterecentmatch', arg)
但是執行上述程式碼時,會報錯 網上查了下原因: 首先,參見1,cursor是cursor型別而非connection型別。 其次,在呼叫儲存過程之後需要執行mysql_store_result()來從服務端取回結果,在python中是在建立cursor時執行該操作,呼叫完一次儲存過程以後未清理,因此會報錯。 由此在迴圈尾部新增cursor.nextset()或者放棄with,手動建立connection,然後將cursor放到for迴圈裡面。
try: conn = pymysql.connect(**self.login) info = self.recentMatch() for i in info: cursor = conn.cursor() ins = list(i) arg = (ins[0], ins[1], ins[2]) cursor.callproc('updaterecentmatch', arg) cursor.close() except Exception as e: print(e) finally: conn.close() # with pymysql.connect(**self.login) as cursor: # info = self.recentMatch() # for i in info: # ins = list(i) # arg = (ins[0], ins[1], ins[2]) # cursor.callproc('updaterecentmatch', arg) # while cursor.nextset() is not None: # pass
參考: