新建config.py文件和opmysql.py文件
config.py
import os
src_path = os.path.dirname(os.path.dirname((os.path.realpath(__file__))))
# print(src_path)
# 当前脚本所在目录的上级目录的绝对路径 E:\PyCharm\pythonProject\2_book
opmysql.py
整体结构
整体结构代码
'''
对于MySQL数据库基本操作的封装
1.单条基本操作 删改更新
2.独立查询单条或多条数据
3.独立添加多条数据
'''
import logging,os,pymysql
from public import config
class OperationDbInterface(object):
# 初始化数据库连接
def __init__(self,host_db='localhost',user_db='root',passwd_db='123456',name_db='test_interface',
port_db=3306,link_type=0):
# 定义1.单条基本操作 删改更新
def op_sql(self,condition):
# 2.独立查询单条数据
def select_one(self,condition):
# 2.独立查询多条数据
def select_all(self,condition):
# 3.独立添加多条数据
def insert_data(self,condition,params):
# 关闭数据库
def __del__(self):
if __name__ == "__main__":
# 实例化
test = OperationDbInterface()
# 查询多条数据
result_select_all = test.select_all("select * from config_total")
# 查询单条数据
result_select_one=test.select_one("select * from config_total where id=1")
# 更改数据
result_op_sql = test.op_sql("update config_total set value_config='test' where id=1")
# 插入数据
result = test.insert_data("insert into config_total(key_config,value_config,description,status)"
"values (%s,%s,%s,%S)",[('mytest1','mytest11','我的测试 1',1),
('mytest2','mytest22','我的测试 2',0)])
print(result_select_all['data'],result_select_all['message'])
print(result_select_one['data'],result_select_one['message'])
print(result_op_sql['data'],result_op_sql['message'])
print(result['data'],result['message'])
# if result['code'] == '0000':
# print(result['data'],result['message'])
# else:
# print(esult['message'])
初始化数据库连接
报错找不到public包
因为public和common是两个包 如果要导的话比较麻烦 我直接把public包拖到common里去了
python模块:自定义模块的3种导入方式
运行代码查看日志输出情况。
路径错误
停止mysql服务再运行,控制台报错找不到文件,发现是代码里的文件路径打错了,/打成了.
中文乱码
路径名改正确之后发现有中文乱码
要在基础配置日志的时候加上编码方式utf-8
改变后结果:
具体代码
# 初始化数据库连接
def __init__(self,host_db='localhost',user_db='root',passwd_db='123456',name_db='test_interface',
port_db=3306,link_type=0):
"""
:param host_db: 数据库服务主机名/IP地址
:param user_db: 数据库用户名
:param passwd_db: 数据库用户密码
:param name_db: 数据库名称
:param port_db: 端口号
:param link_type: 连接类型,link_type=0为字典
"""
try:
if link_type == 0:
# 创建数据库连接,返回字典
self.conn = pymysql.connect(host=host_db,user=user_db,password=passwd_db,db=name_db,port=port_db,
charset='utf8',cursorclass=pymysql.cursors.DictCursor)
else:
# 创建数据库连接,返回元组
self.conn = pymysql.connect(host=host_db, user=user_db, password=passwd_db, db=name_db, port=port_db,
charset='utf8')
self.cur = self.conn.cursor()
except pymysql.Error as e:
print("创建数据库连接失败|Mysql Error %d: %s" % (e.args[0],e.args[1]))
logging.basicConfig(filename=config.src_path +'/log/syserror.log',level=logging.DEBUG,
encoding='utf-8',
format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s')
logger = logging.getLogger(__name__)
logger.exception(e)
# 1.函数:logging.basicConfig()
# 参数讲解:
# (1)level代表高于或者等于这个值时,那么我们才会记录这条日志
# (2)filename代表日志会写在这个文件之中,如果没有这个字段则会显示在控制台上
# (3)format代表我们的日志显示的格式自定义,如果字段为空,那么默认格式为:level:log_name:content import logging
# 2.如何得到一个logger对象
# 实例化;Logger = logging.getLogger()
# Logger.exception 创建一个类似于Logger.error的日志消息
python logger.exception_Python logging设置和logger解析
单条数据更新、删除操作
原本的value_config值为value_test,执行了sql语句后被更改为test。
具体代码
# 定义1.单条基本操作 删改更新
def op_sql(self,condition):
"""
:param condition: SQL语句
:return: 字典
"""
try:
self.cur.execute(condition) # 执行SQL语句 结果存放在游标中
self.conn.commit() # 提交游标数据
result = {'code':'0000','message':'执行通用操作成功','data':[]}
except pymysql.Error as e:
self.conn.rollback() # 回滚
result = {'code':'9999','message':'执行通用操作失败','data':[]}
print("数据库错误|op_sql %d: %s" % (e.args[0], e.args[1]))
logging.basicConfig(filename=config.src_path + '/log/syserror.log', level=logging.DEBUG,
encoding='utf-8',
format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s')
logger = logging.getLogger(__name__)
logger.exception(e)
return result;
单条查询
具体代码
# 2.独立查询单条数据
def select_one(self,condition):
"""
:param condition: SQL语句
:return: 字典
"""
try:
rows_affect = self.cur.execute(condition)
if(rows_affect > 0):
results = self.cur.fetchone(); # 只返回第一条结果
result = {'code':'0000','message':'执行单条查询操作成功','data':results} # data存放查询到的数据 只取一条
else:
result = {'code':'0000','message':'执行单条查询操作成功','data':[]} # 没有查询到数据data为空列表
except pymysql.Error as e:
print("数据库错误|select_one %d: %s" % (e.args[0], e.args[1]))
logging.basicConfig(filename=config.src_path + '/log/syserror.log', level=logging.DEBUG,
encoding='utf-8',
format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s')
logger = logging.getLogger(__name__)
logger.exception(e)
return result;
多条查询
具体代码
# 2.独立查询多条数据
def select_all(self,condition):
"""
:param condition: SQL
:return:
"""
try:
rows_affect = self.cur.execute(condition)
if rows_affect > 0:
self.cur.scroll(0,mode='absolute')
results = self.cur.fetchall() # 返回所有结果 如果没有上一条的话返回
result = {'code':'0000','message':'批量查询操作成功','data':results}
else:
result = {'code':'0000','message':'批量查询操作成功,但未查询到数据','data':[]}
except pymysql.Error as e:
self.conn.rollback()
result = {'code': '9999', 'message': '执行多条查询异常', 'data': []}
print("数据库错误|select_all %d: %s" % (e.args[0], e.args[1]))
logging.basicConfig(filename=config.src_path + '/log/syserror.log', level=logging.DEBUG,
encoding='utf-8',
format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s')
logger = logging.getLogger(__name__)
logger.exception(e)
return result
self.cur.scroll
不明白cur.scroll是干嘛用的
用scroll的前后没有区别,搜了一下:
移动光标,scroll()方法概述 scroll(value, mode) mode缺省值为’relative’,代表相对移动。
当mode='relative’时,value就是移动的长度,value>0向后移动(从位置0移动到位置2),value<0向前移动(比如从位置2移动到位置0)
self.cur.scroll(-2, ‘relative’) 可以缩写为: self.cur.scroll(-2)
当mode='absolute’时,代表绝对移动,value就代表移动的绝对位置,value=0就代表移动到位置0处,就是结果集开头,value=3就是移动到位置3处,也就是第4条记录处。
改了一下代码 self.cur.scroll(1,mode=‘absolute’),从结果集的第二条开始输出,跳过了第一条。
如果直接从头输出其实不需要重置位置,好像会自动回到结果集的初始位置。
插入数据
格式报错
首先 是self.cur.executemany()不是execute()
报错提示会变成这样
executemany()少填了个参数,误以为这条语句的元组列表里的两个数据会直接传进%s里,实际上要由executemany来组合sql语句和参数.
result = test.insert_data("insert into config_total(key_config, value_config, description, status) "
"values (%s, %s, %s, %s)",[('mytest1', 'mytest11', '我的测试1', 1),
('mytest2', 'mytest22', '我的测试2', 2)])
网上没找到关于executemany的详细说明,看了以下pycharm自带的感觉就是executemany将args填进query里。
执行结果
具体代码
# 3.独立添加多条数据
def insert_data(self,condition,params):
"""
:param condition: SQL语句
:param params: 要插入的数据 [('','','',''),('','','','')]
:return: 字典
"""
try:
results = self.cur.executemany(condition,params) # 返回插入数据的条数
self.conn.commit()
result = {'code':'0000','message':'批量插入数据成功','data':results}
except pymysql.Error as e:
self.conn.rollback()
result = {'code':'9999','message':'批量插入数据失败','data':[]}
print("数据库错误|insert_data %d: %s" % (e.args[0], e.args[1]))
logging.basicConfig(filename=config.src_path + '/log/syserror.log', level=logging.DEBUG,
encoding='utf-8',
format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s')
logger = logging.getLogger(__name__)
logger.exception(e)
return result;
result = test.insert_data("insert into config_total(key_config, value_config, description, status) "
"values (%s, %s, %s, %s)",[('mytest1', 'mytest11', '我的测试1', 1),
('mytest2', 'mytest22', '我的测试2', 2)])
关闭数据库
具体代码
# 关闭数据库
def __del__(self):
if self.cur != None:
self.cur.close()
if self.conn != None:
self.conn.close()