随着需要入库的数据越来越多,这样相应的sql操作越来越多;
正好在做单元测试的时候看见laravel中对库操作的封装思想,用过感觉逻辑性很强,索性拿过来;
基础:
FOR Python2.7
import MySQLdb
import MySQLdb.cursors
封装思想:
- 封装Base类,即父类
- 封装操作表(Table)类,即子类
- Table类继承Base类,且在Table类中只操作当前表,也就是说每个表对应一个Table类
- Table类类名称的命名规则:类名即表名,保持一致,这样可以通过获取当前类名称达到获取表名的目的;
具体实现:
Base.py
中
- 定义父类
Base
- 完成连接数据库操作,并获取游标
cursor
- 封装最基础表操作:增删改查及公共方法
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
网友评论