【Python】基於pymysql的資料庫操作類

楊奇龍發表於2017-06-10
一 簡介
     Python和MySQL互動的模組有 MySQLdb 和 PyMySQL(pymysql),MySQLdb是基於C 語言編寫的,而且Python3 不在支援MySQLdb 。PyMySQL是一個純Python寫的MySQL客戶端,它的目標是替代MySQLdb,可以在CPython、PyPy、IronPython和Jython環境下執行,PyMySQL在MIT許可下發布。
    在開發基於Python語言的專案中,為了以後系統能相容Python3,我們使用了PyMySQL替換了MySQLdb。下面我們來熟悉一下pymysql的使用。
 
二 安裝方式
  pymsql的原始碼 ,目前還在持續更新。
  1. 安裝要求:
  2. Python -- one of the following:
  3.      CPython >= 2.6 or >= 3.3
  4.      PyPy >= 4.0
  5.      IronPython 2.7
  6. MySQL Server -- one of the following:
  7.      MySQL >= 4.1 (tested with only 5.5~)
  8.      MariaDB >= 5.1
  9. 安裝
  10.   pip install PyMySQL
   , 強烈建議大家仔細閱讀一遍。其用法和MySQLdb相差無幾,核心用法一致。這樣使用pymysql替換mysqldb的成本極小。


三 基於pymysql的資料庫互動

  1. #!/usr/bin/env python
  2. # encoding: utf-8
  3. """
  4. author: yangyi@youzan
  5. time: 2015/6/8 上午11:34
  6. func: 基於pymysql的資料庫互動類,支援事務提交和回滾,返回結果記錄行數,和insert的最新id
  7. """
  8. import pymysql
  9. from warnings import filterwarnings
  10. filterwarnings('ignore', category=pymysql.Warning)
  11. CONNECT_TIMEOUT = 100
  12. IP = 'localhost'
  13. PORT = 3306
  14. USER = 'root'
  15. PASSSWORD = ''

  16. class QueryException(Exception):
  17.     """
  18.     """


  19. class ConnectionException(Exception):
  20.     """
  21.     """

  22. class MySQL_Utils():
  23.     def __init__(
  24.             self, ip=IP, port=PORT, user=USER, password=PASSSWORD,
  25.             connect_timeout=CONNECT_TIMEOUT, remote=False, socket='', dbname='test'):
  26.         self.__conn = None
  27.         self.__cursor = None
  28.         self.lastrowid = None
  29.         self.connect_timeout = connect_timeout
  30.         self.ip = ip
  31.         self.port = port
  32.         self.user = user
  33.         self.password = password
  34.         self.mysocket = socket
  35.         self.remote = remote
  36.         self.db = dbname
  37.         self.rows_affected = 0


  38.     def __init_conn(self):
  39.         try:
  40.             conn = pymysql.connect(
  41.                     host=self.ip,
  42.                     port=int(self.port),
  43.                     user=self.user,
  44.                     db=self.db,
  45.                     connect_timeout=self.connect_timeout,
  46.                     charset='utf8', unix_socket=self.mysocket)
  47.         except pymysql.Error as e:
  48.             raise ConnectionException(e)
  49.         self.__conn = conn


  50.     def __init_cursor(self):
  51.         if self.__conn:
  52.             self.__cursor = self.__conn.cursor(pymysql.cursors.DictCursor)


  53.     def close(self):
  54.         if self.__conn:
  55.             self.__conn.close()
  56.             self.__conn = None

  57.     #專門處理select 語句
  58.     def exec_sql(self, sql, args=None):
  59.         try:
  60.             if self.__conn is None:
  61.                 self.__init_conn()
  62.                 self.__init_cursor()
  63.             self.__conn.autocommit = True
  64.             self.__cursor.execute(sql, args)
  65.             self.rows_affected = self.__cursor.rowcount
  66.             results = self.__cursor.fetchall()
  67.             return results
  68.         except pymysql.Error as e:
  69.             raise pymysql.Error(e)
  70.         finally:
  71.             if self.__conn:
  72.                 self.close()

  73.     # 專門處理dml語句 delete,updete,insert 
  74.     def exec_txsql(self, sql, args=None):
  75.         try:
  76.             if self.__conn is None:
  77.                 self.__init_conn()
  78.                 self.__init_cursor()
  79.             if self.__cursor is None:
  80.                 self.__init_cursor()


  81.             self.rows_affected=self.__cursor.execute(sql, args)
  82.             self.lastrowid = self.__cursor.lastrowid
  83.             return self.rows_affected
  84.         except pymysql.Error as e:
  85.             raise pymysql.Error(e)
  86.         finally:
  87.             if self.__cursor:
  88.                 self.__cursor.close()
  89.                 self.__cursor = None

  90.     # 提交
  91.     def commit(self):
  92.         try:
  93.             if self.__conn:
  94.                 self.__conn.commit()
  95.         except pymysql.Error as e:
  96.             raise pymysql.Error(e)
  97.         finally:
  98.             if self.__conn:
  99.                 self.close()

  100.     #回滾操作
  101.     def rollback(self):
  102.         try:
  103.             if self.__conn:
  104.                 self.__conn.rollback()
  105.         except pymysql.Error as e:
  106.             raise pymysql.Error(e)
  107.         finally:
  108.             if self.__conn:
  109.                 self.close()
  110.     # 適用於需要獲取插入記錄的主鍵自增id
  111.     def get_lastrowid(self):
  112.         return self.lastrowid
     #獲取dml操作影響的行數
    def get_affectrows(self):
        return self.rows_affected
     #MySQL_Utils初始化的例項銷燬之後,自動提交
     def __del__(self):
        self.commit()
四 小結
   前幾天剛剛將我們的系統中的MySQLdb 替換為PyMySQL, 還未遇到問題。歡迎大家使用測試上述指令碼,有問題歡迎和我討論。如果本文對您有幫助 ,可以贊助 一瓶飲料。




來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/22664653/viewspace-2140569/,如需轉載,請註明出處,否則將追究法律責任。

相關文章