python_mysql封装及思路详解

随着需要入库的数据越来越多,这样相应的sql操作越来越多;
正好在做单元测试的时候看见laravel中对库操作的封装思想,用过感觉逻辑性很强,索性拿过来;

基础:

FOR Python2.7
import MySQLdb
import MySQLdb.cursors

封装思想:

  • 封装Base类,即父类
  • 封装操作表(Table)类,即子类
  • Table类继承Base类,且在Table类中只操作当前表,也就是说每个表对应一个Table类
  • Table类类名称的命名规则:类名即表名,保持一致,这样可以通过获取当前类名称达到获取表名的目的;

具体实现:

Base.py

  • 定义父类Base
  • 完成连接数据库操作,并获取游标cursor
  • 封装最基础表操作:增删改查及公共方法
python_mysql封装及思路详解_第1张图片
一览表
class Base:
    """    
    mysql相关方法
    connect:链接数据库
    creat_table:创建表
    create datebase dbname;
    """
    def __init__(self):
        """   
        链接数据库
        :param kwargs:
        """
        self.db, self.cursor =self.__connect()
    def __connect(self, database='', who='Null'):
        """链接数据库"""
        ip, username, password, database = self.__getConnectData(database, who)#此方法为的读取配置文件的封装方法
        try:
            self.db = MySQLdb.connect(
                ip, username, password, database, charset='utf8',
                 cursorclass=MySQLdb.cursors.DictCursor) 
            return self.db, self.db.cursor()
        except MySQLdb.Error as msg:
            raise msg
    def __sql_contact(self, **kwargs):
    """
    构造和拼接sql语句
    :param data: 查询字段
    :param table: 表名
    :param where: 条件
    :param limit: 返回条数
    :param order: 排序
    :param group: 分组
    :return:
    """
      data = ''
      table = ''
      where = ''
      limit = ''
      order = ''
      group = ''
      if kwargs:
        for key, value in kwargs.items():
            if key =='data':
                data = str(value)
            if key =='table':
                table = str(value)
            if key =='where':
                where = str(value)
            if key =='limit':
                limit = str(value) 
            if key =='order':
                order = str(value)
            if key =='group':
                group = str(value)
      where = ' WHERE ' + where if where else ''
      limit = ' LIMIT ' + limit if limit else ''
      order = ' ORDER BY ' + order if order else '' 
      group = ' GROUP BY ' + group if group else '' 
      data = data if data else '*'
      sql = 'SELECT ' + data + ' FROM ' + table + where + group + order + limit  
      return sql
   def query(self, sql):
    """
    查询表,且带上字段名称
    :param
    :param sql:输出查询语句
    :return:返回字典
    """
    try: 
        cur = self.cursor
        cur.execute(sql)
        index = cur.description
        result = []
        response = cur.fetchall()
        if response:
            for res in response:
                row = {}
                for i in range(len(index)):
                    row[index[i][0]] = res[index[i][0]]
                result.append(row)
            return result
        else:
            return {'status': '0', 'msg': 'result is Null'}
    except Exception as msg:
        print (msg)
        raise
  def select(self, **kwargs):
    """
    查询表
    :param data: 查询字段
    :param table: 表名
    :param where: 条件
    :param limit: 返回条数
    :param order: 排序
    :param group: 分组
    :return: 查询结果
    """
    sql = self.__sql_contact(**kwargs)
    result = self.query(sql)
    return result
  ......

Table类中todo.py

  • 继承Base类
  • 获取表名
  • 重写父类中方法
# coding=utf-8
__author__ = 'xcma'
import os
import sys
from Src.Function.Base import Base
class todo(Base):
    def __init__(self):
        Base.__init__(self)
        self.table = self.__getTableName()
    def __getTableName(self):
        """
        返回当前文件的名称、文件名及路径
        :param is_path:
        :return:
        """
        return os.path.basename(__file__).split('.')[0]
    def select_todo(self, data='', where='', limit='', order='', group=''):
        kwargs = dict(data=data, table=self.table, where=where, limit=limit, order=order, group=group)
        result = Base.select(self, **kwargs)
        return result

注意:**kwargs的使用尽量放在内部调用时使用,暴露在最外层的接口最好将必填参数全部暴露出来,这样在外部调用的时候参数显而易见,在内部调用看起来很简洁;而且配置可变参数会更加灵活些;

总结:

  • mysql类这样封装完以后,业务上需要操作哪个表,就直接引用哪个表文件即可,丝毫不用担心表名是什么;
  • 如果某个操作很常见,则可以提到Base类中,这样对各个表中的复用、重写会很方便;

@雾霾 -2016-12-16 22:01:09

你可能感兴趣的:(python_mysql封装及思路详解)