问题描述:时间过得真快,一眨眼又一个月过去,2022又过去大半,7月的尾巴,终于稍微做出来点 东西,本人也不是开发,也是在不断学习的一枚小白。这次使用tkinter制作了一个mysql的巡检工具,使用图形化操作,边学边操作,一路踩坑,写的不好,但是能交出来一个东西,学习的过程中加深了对class的理解,学习了tkinter布局,如何连接数据库等等。

python:Python 3.8.1

数据库对象:MySQL

一、实现效果

二、问题解决

过程中遇到的问题

1.因为做的是数据库巡检系统,所以登录的账号往往是权限较大的比如root,然后如何去校验root账号,跟正常的管理系统不一样,不是创建好用户和密码表,然后去比对。root是存放在数据库系统中的,没办法去校验root的用户和密码。这里的root是作为参数传进来的,所以如何去比对权限较大的用户呢?

2.显示页面如何去加载数据库中的查询结果呢?按理说应该跟简单,取得数据库查询的返回值,然后加载在页面中。但最后这个显示结果还不是很理想

3.数据库登录的时候如何返回mysql连接给的报错值,如果只设置判断是否登录成功失败很简单,但是在返回mysql报错值的时候如何返回给前台呢

三、代码部分

LoginMain.py

登录类

  1. class Application(Frame):
  2. username = ''
  3. password = ''
  4. ip = ''
  5. port = ''
  6.  
  7. def __init__(self,master=None):
  8. super().__init__(master)
  9. self.master = master
  10. self.pack()
  11. self.createWidget()
  12.  
  13. def createWidget(self): #创建组件容器
  14.  
  15. page = Frame(self)
  16. page.pack()
  17.  
  18. self.usernameGet = StringVar()
  19. self.usernameGet.set('root')
  20. self.passwordGet = StringVar()
  21. self.passwordGet.set('zabbix.9.31')
  22. self.ipGet = StringVar()
  23. self.ipGet.set('192.168.163.21')
  24. self.portGet = StringVar() #这里如果设置IntVar,GUI上会显示0,整数可以为0,不能是空
  25. self.portGet.set('33306')
  26.  
  27. Label(page).grid(row=0,column=0)
  28. Label(page,text='账户:').grid(row=1,column=1)
  29. Entry(page,textvariable=self.usernameGet).grid(row=1,column=2)
  30. Label(page,text='密码:').grid(row=2,column=1)
  31. Entry(page,textvariable=self.passwordGet,show='*').grid(row=2,column=2)
  32. Label(page,text='IP地址:').grid(row=3,column=1)
  33. Entry(page,textvariable=self.ipGet).grid(row=3,column=2)
  34. Label(page,text='端口:').grid(row=4,column=1)
  35. Entry(page,textvariable=self.portGet).grid(row=4,column=2)
  36.  
  37. Button(page,text='登录',command=self.login_check).grid(row=5,column=1,pady=10)
  38. Button(page,text='退出',command=page.quit).grid(row=5,column=2)
  39. def login_check(self):
  40.  
  41. #设置登录退出按钮
  42. i = self.ipGet.get()
  43. p = int(self.portGet.get())
  44. u = self.usernameGet.get()
  45. pa = self.passwordGet.get()
  46. db_name = 'mysql'
  47.  
  48. #实例化Mysql类
  49. mysqlLogin = Mysql(i,p,u,pa,db_name) #这里不能用mysqllogin对象做布尔值判断,只要输入正确,他的布尔值一直是true
  50. results = mysqlLogin.select('select @@version')
  51. print(bool(mysqlLogin));print(bool(results))
  52. if results:
  53. messagebox.showinfo('提示', '连接成功,正在为您生成巡检报告')
  54. # print(type(i),type(p),type(u),type(pa))
  55. self.destroy()
  56. MainPage(root)
  57. mysqlLogin.show()

数据库连接类

  1. class Mysql(object):
  2. # mysql 端口号,注意:必须是int类型
  3. def __init__(self, host, port, user, passwd, db_name):
  4. self.host = host
  5. self.user = user
  6. self.passwd = passwd
  7. self.port = port
  8. self.db_name = db_name
  9.  
  10. def select(self, sql):
  11. """
  12. 执行sql命令
  13. :param sql: sql语句
  14. :return: 元祖
  15. """
  16. try:
  17. conn = pymysql.connect(
  18. host=self.host,
  19. user=self.user,
  20. passwd=self.passwd,
  21. port=self.port,
  22. database=self.db_name,
  23. charset='utf8',
  24. #cursorclass=pymysql.cursors.DictCursor
  25. )
  26. cur = conn.cursor() # 创建游标
  27. # conn.cursor()
  28. cur.execute(sql) # 执行sql命令
  29. #print(type(cur.execute(sql)))
  30. res = cur.fetchall() # 获取执行的返回结果
  31. #print(type(res))
  32. cur.close()
  33. conn.close()
  34. # print(res)
  35. return res
  36. except Exception as e:
  37. messagebox.showerror('提示',e)
  38. return False
  39.  
  40. def show(self):
  41. sql1 = "show global variables"
  42. # sql2 = "show master status;"
  43. # sql3 = "SELECT table_schema,SUM((AVG_ROW_LENGTH*TABLE_ROWS+INDEX_LENGTH))/1024 AS total_KB FROM information_schema.TABLES GROUP BY table_schema ORDER BY total_KB DESC ;"
  44.  
  45. res1 = dict(self.select(sql1))
  46. # res2 = self.select(sql2)
  47. # res3 = self.select(sql3)
  48. filename = r"D:\{}".format('mysql_check.txt')
  49. with open(filename, mode='w', encoding='utf-8') as f:
  50. # 检查MySQL版本
  51. #print("\033[1;32m当前数据库的版本是:\033[0m" + res1['version'])
  52. f.write("当前数据库的版本是:" + res1['version'] + "\n")
  53.  
  54. f.write("当前数据库的version_comment是:" + res1['version_comment'] + "\n")
  55. f.write("当前数据库的version_compile_machine是:" + res1['version_compile_machine'] + "\n")
  56. f.write("当前数据库的version_compile_os是:" + res1['version_compile_os'] + "\n")
  57. f.write("当前数据库的version_compile_zlib是:" + res1['version_compile_zlib'] + "\n")
  58. f.write("当前数据库的sql_mode是:" + res1['sql_mode'] + "\n")
  59.  
  60. # 检查MySQL端口
  61. #print("\033[1;35m当前数据库的端口是:\033[0m" + res1['port'])
  62. f.write("当前数据库的端口是:" + res1['port'] + "\n")
  63. # 检查server_id
  64. #print("\033[1;32m当前数据库的server_id是:\033[0m" + res1['server_id'])
  65. f.write("当前数据库的server_id是:" + res1['server_id'] + "\n")
  66. # 检查basedir目录
  67. #print("\033[1;32m当前数据库的basedir在:\033[0m" + res1['basedir'])
  68. f.write("当前数据库的basedir在:" + res1['basedir'] + "\n")
  69. # 检查datadir目录
  70. #print("\033[1;35m当前数据库的datadir在:\033[0m" + res1['datadir'])
  71. f.write("当前数据库的datadir在:" + res1['datadir'] + "\n")
  72. # 检查tmpdir目录
  73. #print("\033[1;32m当前数据库的tmpdir在:\033[0m" + res1['tmpdir'])
  74. f.write("当前数据库的tmpdir在:" + res1['tmpdir'] + "\n")
  75.  
  76. #pid_file
  77. f.write("当前数据库的pid_file在:" + res1['pid_file'] + "\n")
  78. #optimizer_switch
  79. f.write("当前数据库的optimizer_switch:" + res1['optimizer_switch'] + "\n")
  80. #mysqlx_socket
  81. f.write("mysqlx_socket:" + res1['mysqlx_socket'] + "\n")
  82. #log_bin_basename
  83. f.write("当前数据库的log_bin_basename在:" + res1['log_bin_basename'] + "\n")
  84. #log_error
  85. f.write("当前数据库的log_error在:" + res1['log_error'] + "\n")
  86. #slow_query_log_file
  87. f.write("当前数据库的slow_query_log_file在:" + res1['slow_query_log_file'] + "\n")

MainPage.py

  1. class MainPage:
  2. def __init__(self,master: tk.Tk):
  3. self.root = master
  4. self.root.title('数据库巡检系统')
  5. self.root.geometry('600x400')
  6. self.create_page()
  7. def create_page(self):
  8. self.about_frame = AboutFrame(self.root) #调用views中的aboutframe类,显示关于的信息
  9. # tk.Label(self.about_frame,text = '关于作品:数据库巡检系统').pack()
  10. # tk.Label(self.about_frame,text = '关于作者:我爱睡莲').pack()
  11. # tk.Label(self.about_frame,text = '版权所有:https://www.cnblogs.com/houzhiheng/').pack()
  12.  
  13. self.check_frame = CheckFrame(self.root)
  14.  
  15. menubar = tk.Menu(self.root)
  16. menubar.add_command(label='巡检结果',command=self.show_check)
  17. menubar.add_command(label='关于',command=self.show_about)
  18. self.root['menu'] = menubar
  19.  
  20. def show_check(self):
  21. self.check_frame.pack()
  22. self.about_frame.pack_forget() #选择性遗忘其他加载过的页面,要不然都会加载在页面当中
  23.  
  24. def show_about(self):
  25. self.about_frame.pack()
  26. self.check_frame.pack_forget()

views.py

显示关于部分类

  1. class AboutFrame(tk.Frame):
  2. def __init__(self,root):
  3. super().__init__(root)
  4. tk.Label(self, text='Production:数据库巡检系统').pack()
  5. tk.Label(self, text='Author:我爱睡莲').pack()
  6. tk.Label(self, text='Version:1.0').pack()
  7. tk.Label(self, text='@Copyright:https://www.cnblogs.com/houzhiheng/').pack()

显示数据库巡检结果类

  1. class CheckFrame(tk.Frame):
  2. def __init__(self,root):
  3. super().__init__(root)
  4. # tk.Label(self, text='巡检结果').pack()
  5. self.table_view = tk.Frame()
  6. self.table_view.pack()
  7.  
  8. self.create_page()
  9.  
  10. tk.Button(self,text='保存文件',command=self.save_data_frame).pack(anchor=tk.E,pady=5)
  11.  
  12. def create_page(self):
  13. # self.tree_view = ttk.Treeview(self,show='headings')
  14. # columns = ("check_results")
  15. # columns_values = ("数据库巡检报告")
  16. # top = Tk() # 设置窗口
  17. # sb = Scrollbar(top) # 设置窗口滚动条
  18. # sb.pack(side=RIGHT, fill=) # 设置窗口滚动条位置
  19. # self.sb = Scrollbar()
  20. # self.sb.pack(side=RIGHT,fill= Y)
  21. # self.tree_view = ttk.Treeview(self,show='headings',columns=columns)
  22. # self.tree_view.column('check_results',width=500,anchor='center')
  23. # self.tree_view.heading('check_results',text=columns_values)
  24. # self.tree_view.pack(fill=tk.BOTH,expand=True)
  25. # self.show_data_frame()
  26.  
  27. with open(r'D:\mysql_check.txt', 'r', encoding='utf-8') as f:
  28. lines2 = [l.split() for l in f.readlines() if l.strip()]
  29. # 滚动条初始化(scrollBar为垂直滚动条,scrollBarx为水平滚动条)
  30. scrollBar = Scrollbar(self)
  31. scrollBarx = Scrollbar(self, orient=HORIZONTAL)
  32. # 靠右,充满Y轴
  33. scrollBar.pack(side=RIGHT, fill=Y)
  34. # 靠下,充满X轴
  35. scrollBarx.pack(side=BOTTOM, fill=X)
  36. lb = Text(self, width=100, height=25,)
  37. lb.pack()
  38. # db = Mysql('192.168.163.21', 33306, 'root', 'zabbix.9.31', 'mysql')
  39. # res = db.show()
  40.  
  41. textvar = "1:{} \n2:{}\n3:{}\n4:{}\n5:{}\n6:{}\n7:{}\n8:{}\n9:{}\n10:{}\n11:{}\n12:{}\n13:{}\n14:{}\n15:{}"\
  42. .format(lines2[0],lines2[1],lines2[2],lines2[3],lines2[4],lines2[5],lines2[6],lines2[7],lines2[8],lines2[9],lines2[10],lines2[11],lines2[12],lines2[13],lines2[14],lines2[15],lines2[16])
  43. lb.insert('insert', textvar + '\n')
  44. lb.update()
  45. # 而当用户操纵滚动条的时候,自动调用 Treeview 组件的 yview()与xview() 方法
  46. # 即滚动条与页面内容的位置同步
  47. scrollBar.config(command=lb.yview)
  48. scrollBarx.config(command=lb.xview)
  49.  
  50. def show_data_frame(self): #把查询的内容输出到屏幕上来
  51. pass
  52. def save_data_frame(self):
  53. messagebox.showinfo('提示','您的文件已保存在D:\mysql_check.txt中!')

四、结论与收获

问题处理:

1.如何去对比root登录是否成功呢,从上面代码可以看到,我没法去直接登录数据库去校验用户名和密码,但是我可以让用户名登录成功去执行命令来判断是否登录成功,如果root登陆并且成功执行命令,我就返回一个结果为TRUE,如果执行失败,就返回一个结果为FALSE,这条命令是去查询数据库自身版本得到,任何用户都可以执行

2.在屏幕上输出巡检的结果,本来取得数据库返回值然后给屏幕上就可以了,但是我的views.py调用class MySQL类失败,所以最后直接把查询结果保存在了文件中,前台输出的时候打开文件,然后调整文件格式就输出了,败笔啊这一步

3.将mysql连接返回的报错做成异常处理即可,只不过当时做的时候逻辑有一点问题一直没显示成功

结论收获:

本来是想做一个全套的数据库巡检GUI系统,桌面版本的已经做好了,但是没有到光做一个GUI+mysql版本的就花费了两周时间了,不过这个大体结构成型,后边如果想做应该会简单些。这次更加深刻了解了面向对象,上学没学好,毕业了都得补回来

python:GUI图形化数据库巡检工具的更多相关文章

  1. python GUI图形化编程-----wxpython

    一.python gui(图形化)模块介绍: Tkinter :是python最简单的图形化模块,总共只有14种组建 Pyqt     :是python最复杂也是使用最广泛的图形化 Wx       ...

  2. MariaDb数据库管理系统学习(二)使用HeidiSQL数据库图形化界面管理工具

    HeidiSQL 是一款用于简单化的 MySQL server和数据库管理的图形化界面.该软件同意你浏览你的数据库,管理表,浏览和编辑记录,管理用户权限等等.此外,你能够从文本文件导入数据,执行 SQ ...

  3. 黑马程序员:Java基础总结----GUI图形化界面

    黑马程序员:Java基础总结 GUI图形化界面   ASP.Net+Android+IO开发 . .Net培训 .期待与您交流!   GUI(Graphical User Interface)图形化界 ...

  4. [.net 面向对象程序设计进阶] (26) 团队开发利器(五)分布式版本控制系统Git——图形化Git客户端工具TortoiseGit

    [.net 面向对象程序设计进阶] (26) 团队开发利器(五)分布式版本控制系统Git——图形化Git客户端工具TortoiseGit 读前必备: 接上篇: 分布式版本控制系统Git——使用GitS ...

  5. Atiti  qq空间破解(3)------------gui图形化通用cli执行器atiuse

    Atiti  qq空间破解(3)------------gui图形化通用cli执行器atiuse 结构:::命令行+以及反馈log框1 cli_guiUI/index.htm1 /AtiPlatf_c ...

  6. zookeeper图形化的客户端工具

    追加一个zookeeper图形化的客户端工具: 1.zookeeper图像化客户端工具的下载地址:https://issues.apache.org/jira/secure/attachment/12 ...

  7. 品味性能之道<六>:图形化SQL分析工具

         在上一章里,重点分享了命令行SQL分析工具的使用方法.在本章将重点分享PL/SQL的SQL分析工具. 一.如何打开PL/SQL执行计划      开启PL/SQL这工具,推荐如下方法: 点击 ...

  8. zookeeper系列(一)zookeeper图形化的客户端工具

    追加一个zookeeper图形化的客户端工具: 1.zookeeper图像化客户端工具的下载地址:https://issues.apache.org/jira/secure/attachment/12 ...

  9. python数据图形化—— matplotlib 基础应用

    matplotlib是python中常用的数据图形化工具,用法跟matlab有点相似.调用简单,功能强大.在Windows下可以通过命令行 pip install matplotlib 来进行安装. ...

随机推荐

  1. 网络:Tor

    洋葱路由催生了暗网的产生 1995年,美国海军研究实验室的科学家开始开发一套匿名系统,可以避免人们在互联网上的行迹被追 踪到.由于在该系统中,数据被层层密码保护,这个技术被称为叫作"洋葱路由 ...

  2. 好客租房39-react组件基础总结

    1组件的两种创建方式:函数组件和类组件 2无状态函数组件 负责静态结构展示 3有状态组件 负责更新ui 让页面动起来 4绑定事件注意this指向问题 5使用受控组件创建表单 6完全利用js语言的能够力 ...

  3. linux篇-linux mysql数据库定时备份

    1在linux上面创建一个文件夹,并且进行备份 cd /home mkdir backup cd backup 2创建一个脚本 Vi imaginebase.sh #!/bin/bash mysqld ...

  4. 腾讯产品快速尝鲜,蓝鲸智云社区版V6.1灰度测试开启

    这周小鲸悄悄推送了社区版V6.1(二进制部署版本,包含基础套餐.监控日志套餐),没过一天就有用户来问6.1的使用问题了.小鲸大吃一鲸,原来你还是爱我的. ![请添加图片描述](https://img- ...

  5. JAVA - 启动线程有哪几种方式

    JAVA - 启动线程有哪几种方式 一.继承Thread类创建线程类 (1)定义Thread类的子类,并重写该类的run方法,该run方法的方法体就代表了线程要完成的任务.因此把run()方法称为执行 ...

  6. Bean Validator

    Bean Validator 关于Jakarta EE 2018年03月, Oracle 决定把 JavaEE 移交给开源组织 Eclipse 基金会,并且不再使用Java EE这个名称. 因此jav ...

  7. vue内容拖拽放大缩小

    <!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  8. BUUCTF-菜刀666

    菜刀666 这题和之前做过的流量题不同,对我还是有些难度.看了看大佬的wp才做出来的 wireshark打开流量包,一开始只是单纯过滤http,包很多,看花了眼,看了好多也没觉得有啥异常. 后面才知道 ...

  9. BUUCTF-神秘龙卷风

    神秘龙卷风 通过提示知道压缩包密码是四位纯数字,通过爆破得到 得到一串编码 看样子应该是brainfuck编码 flag{e4bbef8bdf9743f8bf5b727a9f6332a8}

  10. Python基础学习笔记_01

    Python的介绍 1989年圣诞节创造,1991年正真出生,目前更新到3.0版本 具有最庞大的"代码库",人称"胶水语言",无所不能 一种跨平台的计算机程序设 ...