Python3 初学实践案例(8)使用 sqlite3 数据库存储生成的密码,prettytable 的使用
来源:互联网 发布:视频网络传输 编辑:程序博客网 时间:2024/04/29 07:48
Python3 初学实践案例(8)使用 sqlite3 数据库存储生成的密码,prettytable 的使用
在前面我用 python
脚本实现的 cli
版本的密码生成与管理工具中,我使用文本文件来存储我们的生成的密码。详情见:http://blog.csdn.net/fungleo/article/details/78842597
这样做我感觉还是有一些欠妥。因为这样查看的时候,必须使用系统命令,或者其他 GUI 工具进行查看。如果我要用 python
来处理和分析这个文本文件,无疑工作量是巨大的。
因此,我希望用数据库来存储我们生成的密码,然后用 sql
语句来进行查询,顺便写一个查询工具,这样就可以很方便的使用了。
在数据库的选型上,我决定使用单文件数据库 sqlite
。因为这样我们不需要安装一个数据库服务,并且可以随时复制走。
再说,就一个表就可以搞定的事情,搞个大型数据库也确实有点脱裤子放屁的感觉。
本文是
cli
密码生成管理工具的衍生文章。
开始实战
由于前面我们已经完成了密码生成工具的主体逻辑代码,这边只是将原来使用文本文件存储密码修改为数据库存储,所以,我不想大幅修改原有的文件。因此我新创建了一个 db.py
文件,来专门写相应的代码。
全部代码如下:
#!/usr/bin/env python3# -*- coding: UTF-8 -*-import sqlite3import reimport sysfrom prettytable import PrettyTableDB_PATH = sys.path[0] + '/passwd.db'def checkDB(db): db.execute('''SELECT name FROM sqlite_master WHERE type IN ('table','view') AND name NOT LIKE 'sqlite_%' ORDER BY 1''') o = db.fetchall() if len(o) == 0 or not bool(re.search(r'(\'passwd\',)',str(o))): db.execute('''CREATE TABLE passwd ( id integer primary key autoincrement, name varchar(255), password varchar(255), time timestamp default current_timestamp )''')def insertDb(name,passwd): conn = sqlite3.connect(DB_PATH) c = conn.cursor() checkDB(c) c.execute("INSERT INTO passwd (name,password) VALUES ('" + name + "', '" + passwd + "')"); conn.commit() conn.close()def selectDb(pid,name): conn = sqlite3.connect(DB_PATH) c = conn.cursor() checkDB(c) select = "SELECT * from passwd " if name: select += ('where name LIKE \'%' + name + '%\'') if pid: select += ('where id = \'' + str(pid) + '\'') select += 'ORDER BY id DESC' res = list(c.execute(select)) if len(res) == 0: print('Info: record is empty') else: x = PrettyTable(['id','name','password','time']) x.align['name'] = 'l' x.padding_width = 1 for row in res: x.add_row(list(row)) print(x) conn.close()def deleteDb(pid): conn = sqlite3.connect(DB_PATH) c = conn.cursor() checkDB(c) c.execute('DELETE from passwd where id=' + str(pid) ) conn.commit() o = conn.total_changes if o == 0: print('Failure: the password was not found') if o == 1: print('Success: ID ' + str(pid) + ' password has been deleted') conn.close()
代码解析
确定数据库路径
我们的脚本写好后,我们可以在系统的任何地方运行这个脚本。因此,数据库路径必须使用绝对路径,否则存在哪里就不太清楚了。
我希望文件存储在和 db.py
文件的同级目录下,因此,我需要先获取到 db.py
这个文件所在的目录。我们使用 sys
库的基本功能来实现,代码如下:
import sysDB_PATH = sys.path[0] + '/passwd.db'
其中 sys.path[0]
就是获取文件存在的绝对路径,后面加上数据库文件名。然后存一个常量,我们就可以在下面的函数中使用数据库位置常量来调用数据库了。
sqlite 数据库的连接
首先,我们需要引入库,然后创建连接,连接打开后,我们执行我们希望操作的 sql
语句,然后再关闭连接,就完成了我们希望的工作了。
import sqlite3conn = sqlite3.connect(DB_PATH)c = conn.cursor()c.execute("__这里是一条SQL语句__");conn.commit()conn.close()
如上,基本就是一条 sql
语句的执行全过程了。当然,我们可以在一个连接内操作多条 SQL
语句,但是就我们的这个工具来说,一般都是一条一条的执行,需要执行的时候创建连接,连接好了之后,我们执行代码,然后提交,然后关闭。
如果数据库不存在,就会创建一个数据库文件,这个是个自动的机制,我们就不用管了。
在数据库中创建表
一个新创建的数据库当中是没有任何表的。我们不能要求我们的用户自己去搞好一个表再来使用。因此,当数据库不存在,在第一次链接的时候会自动创建这个数据库,但是这个数据库中是没有任何表的,所以,我们需要检查数据库中有没有表,如果有表,那么有没有我们使用的这个表,如果不符合条件,我们则需要创建一个表,并且这个表的结构要符合我们的设计。
整体代码如下:
import redef checkDB(db): db.execute('''SELECT name FROM sqlite_master WHERE type IN ('table','view') AND name NOT LIKE 'sqlite_%' ORDER BY 1''') o = db.fetchall() if len(o) == 0 or not bool(re.search(r'(\'passwd\',)',str(o))): db.execute('''CREATE TABLE passwd ( id integer primary key autoincrement, name varchar(255), password varchar(255), time timestamp default current_timestamp )''')
如上,我们这个函数的作用就是检查状况,如果需要创建一个表,就直接创建。那么,在我们需要检查的地方,使用这个函数就可以检查了,如下代码:
def insertDb(name,passwd): conn = sqlite3.connect(DB_PATH) c = conn.cursor() # 就是这里,我先检查了一下。 checkDB(c) c.execute("INSERT INTO passwd (name,password) VALUES ('" + name + "', '" + passwd + "')"); conn.commit() conn.close()
上面我使用了正则来检查数据库中是否存在我们需要的
passwd
表,所以我们需要引入正则库。
优雅的在终端内展示表格
我们可以使用 select
语句从数据库中查出来内容,然后使用 list()
方法就可以转换成可以循环的列表。但是如何优雅的在终端内展示表格呢?这里,我使用了一个 python
的库 prettytable
来解决我的问题。
不使用
list()
函数也可以循环的。
演示如下:
from prettytable import PrettyTable# 从数据库拿到结果,转换成列表res = list(c.execute(select))# 给输出的表格设定表头,有几列就设定几个x = PrettyTable(['id','name','password','time'])# 可以给指定列设定文字对齐,默认是居中对齐,下面是改成了 left 左对齐x.align['name'] = 'l'# 设定表格内填充为 1 个空格,让表格可读性更高x.padding_width = 1# 循环数据for row in res: # 插入每一行的数据 x.add_row(list(row))# 打印表格print(x)
好,这样我们就可以输出优雅的表格了。其结果如下:
+----+--------------+------------+---------------------+| id | name | password | time |+----+--------------+------------+---------------------+| 4 | 123 | zTAT8DCU | 2017-12-20 08:31:35 || 3 | sunmingyuan2 | TxmKZt:44s | 2017-12-20 05:11:36 || 2 | sunmingyuan | /t22664Q44 | 2017-12-20 05:11:22 |+----+--------------+------------+---------------------+
其他内容都是基础的 sql
语句的内容。更多 sql
内容可以访问 http://www.w3school.com.cn/sql/index.asp 获取。
补充查看和删除密码的管理脚本 seepw.py 代码
上面我们的 db.py
脚本中,除了生成密码的脚本中我们需要的插入语句外,我还写了查看以及删除语句的函数。我使用了另外一个脚本 seepw.py
来实现相应的功能。其代码如下:
#!/usr/bin/env python3# -*- coding: UTF-8 -*-import dbimport argparseif __name__ == '__main__': parser = argparse.ArgumentParser() parser.description='This program is used to manage the password saved in the database' parser.add_argument("-v", "--version",action='version', version='%(prog)s 1.0') group = parser.add_mutually_exclusive_group() group.add_argument("-i", "--id", help="The ID of the password you want to look at") group.add_argument("-n", "--name", help="The NAME of the password you want to look at") group.add_argument("-d", "--delete", help='Delete mode, the parameter is ID') args = parser.parse_args() name = args.name if args.name else False pId = args.id if args.id else False dId = args.delete if dId: if dId.isdigit(): db.deleteDb(dId) else: print('Error: The parameters of the delete mode must be number') else: db.selectDb(pId,name)
这个脚本没什么更多的解释,只是去配置了 argparse
库的各种参数然后判断用户是想查看还是删除,然后执行对应的方法即可。
补充生成密码的修改
首先是去除原有的使用文本文件存储的所有代码,引用我们的 db.py
文件,然后在需要插入密码到数据库的地方使用下面的方法即可往数据库中插入保存的数据。
db.insertDb(name,passwd)
接下来我会抽时间写一个一键安装脚本,到时候放到 github
上面,给大家使用。
本文由 FungLeo 原创,允许转载,但转载必须保留首发链接。
- Python3 初学实践案例(8)使用 sqlite3 数据库存储生成的密码,prettytable 的使用
- Python3 初学实践案例(9)sqlacodegen 根据已有数据库生成 ORM 使用的 model.py
- Python3 初学实践案例(7)tkinter 入门 GUI 的密码生成程序
- Python3 初学实践案例(4)可设定长度和密码复杂级别的生成密码脚本
- Python3 初学实践案例(5)可设定长度和密码复杂级别的生成密码脚本另一种思路
- Python3 初学实践案例(3)argparse 命令行参数库的使用
- Python3 初学实践案例(1)按条件生成复杂密码
- Python3 初学实践案例(6)终极 CLI 密码生成程序实现
- Python3 初学实践案例(12)将源目录中的图片根据设定最长边参数保存到目标目录脚本(Image 的使用)
- sqlite3数据库的使用
- sqlite3数据库的使用
- sqlite3数据库的使用
- Python3 初学实践案例(11)判断质数以及计算一个数字的质因数
- iOS开发中 SQLite3的使用案例
- C++使用Sqlite3的简单案例
- 举例数据库sqlite3的使用
- 【iOS】数据库SQLite3的使用
- iOS Sqlite3 数据库的使用
- 【多线程】三种方案实现多线程之间相互协作的通信
- Centos 6.5 rsync+inotify 两台服务器文件实时同步
- 实验六 排序
- go语言工程管理
- 浅谈生成树计数问题,以SPOJ HIGH, BZOJ 4894, BZOJ 1016为例
- Python3 初学实践案例(8)使用 sqlite3 数据库存储生成的密码,prettytable 的使用
- Latex 绘制函数图像
- dorado关于下拉框的的onSelect()方法
- Oracle SQL查询1--171220--oracle-sql
- 【给詹詹的Python学习笔记一】
- Spring+MyBatis 错误:org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.b
- 学习笔记-关于使程序暂停的3种方法
- solr5 配置增量更新
- 斯坦福大学机器学习作业题Problem Set #1: Supervised Learning Logistic regression