1. 程式人生 > >使用pyMySQL連線資料庫時遇到的幾個問題

使用pyMySQL連線資料庫時遇到的幾個問題

最近幾天在折騰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

參考: