python數(shù)據(jù)庫類封裝

import pymysql
from log import MyLog as Log


class DbModel:
    # 數(shù)據(jù)庫連接對象
    __db = None
    # 游標(biāo)對象
    __cursor = None

    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        return self

    def __new__(self, *args, **kwargs):
        if not hasattr(self, '_instance'):
            self._instance = super().__new__(self)
            # 主機(jī)
            host = 'host' in kwargs and kwargs['host'] or 'localhost'
            # 端口
            port = 'port' in kwargs and kwargs['port'] or '3306'
            # 用戶名
            user = 'user' in kwargs and kwargs['user'] or 'root'
            # 密碼
            passwd = 'passwd' in kwargs and kwargs['passwd'] or '123456'
            # 數(shù)據(jù)庫
            db = 'db' in kwargs and kwargs['db'] or 'mypython'
            # 編碼
            charset = 'charset' in kwargs and kwargs['charset'] or 'utf8mb4'
            # 打開數(shù)據(jù)庫連接
            Log.info('連接數(shù)據(jù)庫')
            self.__db = pymysql.connect(host = host, port = int(port), user = user, passwd = passwd, db = db, charset = charset)
            # 創(chuàng)建一個游標(biāo)對象 cursor
            # self.__cursor = self.__db.cursor()
            self.__cursor = self.__db.cursor(cursor = pymysql.cursors.DictCursor)
        return self._instance

    # 返回執(zhí)行execute()方法后影響的行數(shù)
    def execute(self, sql):
        Log.info(sql)
        self.__cursor.execute(sql)
        rowcount = self.__cursor.rowcount
        return rowcount

    def query(self, sql):
        Log.info(sql)
        self.__cursor.execute(sql)
        results = self.__cursor.fetchall()
        return results

    # 增->返回新增ID
    def insert(self, **kwargs):
        table = kwargs['table']
        cell = kwargs['cell']
        del kwargs['table']
        sql = 'insert into %s set ' % table
        for k, v in cell.items():
            sql += "`%s`='%s'," % (k, v)
        sql = sql.rstrip(',')
        Log.info(sql)
        try:
            # 執(zhí)行SQL語句
            self.__cursor.execute(sql)
            # 提交到數(shù)據(jù)庫執(zhí)行
            self.__db.commit()
            # 獲取自增id
            res = self.__cursor.lastrowid
            return res
        except Exception as e:
            Log.error(str(e))
            # 發(fā)生錯誤時回滾
            self.__db.rollback()

    # 刪->返回影響的行數(shù)
    def delete(self, **kwargs):
        table = kwargs['table']
        where = kwargs['where']
        sql = 'DELETE FROM %s where %s' % (table, where)
        Log.info(sql)
        try:
            # 執(zhí)行SQL語句
            self.__cursor.execute(sql)
            # 提交到數(shù)據(jù)庫執(zhí)行
            self.__db.commit()
            # 影響的行數(shù)
            rowcount = self.__cursor.rowcount
            return rowcount
        except Exception as e:
            Log.error(str(e))
            # 發(fā)生錯誤時回滾
            self.__db.rollback()

    # 改->返回影響的行數(shù)
    def update(self, **kwargs):
        table = kwargs['table']
        cell = kwargs['cell']
        # del kwargs['table']
        kwargs.pop('table')

        where = kwargs['where']
        kwargs.pop('where')

        sql = 'update %s set ' % table
        for k, v in cell.items():
            sql += "`%s`='%s'," % (k, v)
        sql = sql.rstrip(',')
        sql += ' where %s' % where
        Log.info(sql)
        try:
            # 執(zhí)行SQL語句
            self.__cursor.execute(sql)
            # 提交到數(shù)據(jù)庫執(zhí)行
            self.__db.commit()
            # 影響的行數(shù)
            rowcount = self.__cursor.rowcount
            return rowcount
        except Exception as e:
            Log.error(str(e))
            # 發(fā)生錯誤時回滾
            self.__db.rollback()

    def insert_many(self, **kwargs):
        table = kwargs.get('table')
        data = kwargs.get('data')
        query = ""
        duplicate = kwargs.get('duplicate')
        values = []
        for data_dict in data:
            if not query:
                columns = ', '.join('`{0}`'.format(k) for k in data_dict)
                place_holders = ', '.join('%s'.format(k) for k in data_dict)
                query = "INSERT INTO {0} ({1}) VALUES ({2})".format(table, columns, place_holders)
                if duplicate:
                    duplicateStr = ', '.join('`{0}`=VALUES(`{1}`)'.format(k, k) for k in duplicate)
                    query = query + " ON DUPLICATE KEY UPDATE {0}".format(duplicateStr)
            v = list(data_dict.values())[:]
            values.append(v)
        Log.info(query)
        try:
            # 執(zhí)行SQL語句
            self.__cursor.executemany(query, values)
            # 提交到數(shù)據(jù)庫執(zhí)行
            self.__db.commit()
            # 影響的行數(shù)
            rowcount = self.__cursor.rowcount
            return rowcount
        except Exception as e:
            Log.error(str(e))
            # 發(fā)生錯誤時回滾
            self.__db.rollback()

    # 查->單條數(shù)據(jù)
    def fetchone(self, **kwargs):
        table = kwargs['table']
        # 字段
        field = 'field' in kwargs and kwargs['field'] or '*'
        # where
        where = 'where' in kwargs and 'where ' + kwargs['where'] or ''
        # order
        order = 'order' in kwargs and 'order by ' + kwargs['order'] or ''

        sql = 'select %s from %s %s %s limit 1' % (field, table, where, order)
        Log.info(sql)
        try:
            # 執(zhí)行SQL語句
            self.__cursor.execute(sql)
            # 使用 fetchone() 方法獲取單條數(shù)據(jù).
            data = self.__cursor.fetchone()
            return data
        except Exception as e:
            Log.error(str(e))
            # 發(fā)生錯誤時回滾
            self.__db.rollback()

    # 查->多條數(shù)據(jù)
    def fetchall(self, **kwargs):
        table = kwargs['table']
        # 字段
        field = 'field' in kwargs and kwargs['field'] or '*'
        # where
        where = 'where' in kwargs and 'where ' + kwargs['where'] or ''
        # order
        order = 'order' in kwargs and 'order by ' + kwargs['order'] or ''
        # limit
        limit = 'limit' in kwargs and 'limit ' + kwargs['limit'] or ''
        sql = 'select %s from %s %s %s %s' % (field, table, where, order, limit)
        Log.info(sql)
        try:
            # 執(zhí)行SQL語句
            self.__cursor.execute(sql)
            # 使用 fetchone() 方法獲取單條數(shù)據(jù).
            data = self.__cursor.fetchall()
            return data
        except Exception as e:
            Log.error(str(e))
            # 發(fā)生錯誤時回滾
            self.__db.rollback()

    # 析構(gòu)函數(shù)蚕钦,釋放對象時使用
    def __del__(self):
        # 關(guān)閉數(shù)據(jù)庫連接
        self.__db.close()
        print('關(guān)閉數(shù)據(jù)庫連接')

"""
封裝log方法
"""

import os
import time
import platform
import logging.handlers

# 日志打印等級
LEVELS = {
    'debug': logging.DEBUG,
    'info': logging.INFO,
    'warning': logging.WARNING,
    'error': logging.ERROR,
    'critical': logging.CRITICAL
}

# 創(chuàng)建一個日志
logger = logging.getLogger()
level = 'default'


# 創(chuàng)建日志文件方法
def create_file(filename):
    path = filename[0:filename.rfind('/')]
    if not os.path.isdir(path):
        os.makedirs(path)
    if not os.path.isfile(filename):
        fd = open(filename, mode = 'w', encoding = 'utf-8')
        fd.close()
    else:
        pass


# 給logger添加handler 添加內(nèi)容到日志句柄中
def set_handler(levels):
    if levels == 'error':
        logger.addHandler(MyLog.err_handler)
    logger.addHandler(MyLog.handler)


# 在記錄日志之后移除句柄
def remove_handler(levels):
    if levels == 'error':
        logger.removeHandler(MyLog.err_handler)
    logger.removeHandler(MyLog.handler)


def get_current_time():
    return time.strftime(MyLog.date, time.localtime(time.time()))


class MyLog:
    path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    host_os = platform.system()
    if host_os == 'Linux':
        log_file = r'/var/log/info.log'
        err_file = r'/var/log/err.log'
    else:
        log_file = path + '/Log/info.log'
        err_file = path + '/Log/err.log'
    logger.setLevel(LEVELS.get(level, logging.NOTSET))
    create_file(log_file)
    create_file(err_file)
    date = '%Y-%m-%d %H:%M:%S'

    # 創(chuàng)建一個handler辟宗,用于寫入日志文件
    handler = logging.FileHandler(log_file, encoding = 'utf-8')
    err_handler = logging.FileHandler(err_file, encoding = 'utf-8')

    @staticmethod
    def debug(log_meg):
        set_handler('debug')
        # 文件中輸出模式
        logger.debug("[" + get_current_time() + "] - [DEBUG]:" + log_meg)
        remove_handler('debug')

    @staticmethod
    def info(log_meg):
        set_handler('info')
        logger.info("[" + get_current_time() + "] - [INFO]:" + log_meg)
        remove_handler('info')

    @staticmethod
    def warning(log_meg):
        set_handler('warning')
        logger.warning("[" + get_current_time() + "] - [WARNING]:" + log_meg)
        remove_handler('warning')

    @staticmethod
    def error(log_meg):
        set_handler('error')
        logger.error("[" + get_current_time() + "] - [ERROR]:" + log_meg)
        remove_handler('error')

    @staticmethod
    def critical(log_meg):
        set_handler('critical')
        logger.error("[" + get_current_time() + "] - [CRITICAL]:" + log_meg)
        remove_handler('critical')

    # # 設(shè)置控制臺輸出格式
    # formatter = logging.Formatter(
    #     '[%(asctime)s] [%(levelname)s] %(message)s', '%Y-%m-%d %H:%M:%S')
    # # 再創(chuàng)建一個handler欧引,用于輸出到控制臺
    # console = logging.StreamHandler()
    # console.setFormatter(formatter)
    # logger.addHandler(console)
    # console.setLevel(logging.NOTSET)


if __name__ == "__main__":
    MyLog.debug("This is debug message")
    MyLog.info("This is info message")
    MyLog.warning("This is warning message")
    MyLog.error("This is error")
    MyLog.critical("This is critical message")
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末蹬刷,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,000評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件违帆,死亡現(xiàn)場離奇詭異,居然都是意外死亡金蜀,警方通過查閱死者的電腦和手機(jī)刷后,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,745評論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來渊抄,“玉大人尝胆,你說我怎么就攤上這事』よ耄” “怎么了含衔?”我有些...
    開封第一講書人閱讀 168,561評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我贪染,道長缓呛,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,782評論 1 298
  • 正文 為了忘掉前任杭隙,我火速辦了婚禮哟绊,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘痰憎。我一直安慰自己票髓,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 68,798評論 6 397
  • 文/花漫 我一把揭開白布信殊。 她就那樣靜靜地躺著炬称,像睡著了一般。 火紅的嫁衣襯著肌膚如雪涡拘。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,394評論 1 310
  • 那天据德,我揣著相機(jī)與錄音鳄乏,去河邊找鬼。 笑死棘利,一個胖子當(dāng)著我的面吹牛橱野,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播善玫,決...
    沈念sama閱讀 40,952評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼水援,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了茅郎?” 一聲冷哼從身側(cè)響起蜗元,我...
    開封第一講書人閱讀 39,852評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎系冗,沒想到半個月后奕扣,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,409評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡掌敬,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,483評論 3 341
  • 正文 我和宋清朗相戀三年惯豆,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片奔害。...
    茶點故事閱讀 40,615評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡楷兽,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出华临,到底是詐尸還是另有隱情芯杀,我是刑警寧澤,帶...
    沈念sama閱讀 36,303評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站瘪匿,受9級特大地震影響跛梗,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜棋弥,卻給世界環(huán)境...
    茶點故事閱讀 41,979評論 3 334
  • 文/蒙蒙 一核偿、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧顽染,春花似錦漾岳、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,470評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至唧垦,卻和暖如春捅儒,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背振亮。 一陣腳步聲響...
    開封第一講書人閱讀 33,571評論 1 272
  • 我被黑心中介騙來泰國打工巧还, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人坊秸。 一個月前我還...
    沈念sama閱讀 49,041評論 3 377
  • 正文 我出身青樓麸祷,卻偏偏與公主長得像,于是被迫代替她去往敵國和親褒搔。 傳聞我的和親對象是個殘疾皇子阶牍,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,630評論 2 359

推薦閱讀更多精彩內(nèi)容