一、背景
最近有个想法,想写一个软件,前期本来想用java的springboot加vue来实现,数据库选sqlite来存储,但在用spingboot框架搭好之后,感觉这款软件更适合用python来写,java不适windows桌面系统,最终选择了pthon使用tkinter gui来实现。sqlite数据库方便是方便,但开源版本不能设置密码,可以设置密码的商业版本一年需要499美元一年,太贵了,不适合此软件,但为了数据的安全时,又必须对sqlite加密,所以在编译pysqlcipher3的道路上,遇到了各种奇葩问题,百度上搜的结果信息也很少,而且几乎零零散散的,感觉国内在使用python+sqlite做项目的太少了,百度上针对此搜索结果也非常少,所以将此整理出来,供大家参考使用(为什么选择sqlcipher3,而不是sqlcipher4,是因为截止到写博文当天,sqlalchemy使用sqlcipher只能支持到3,不支持4)
二、说明
此项目最大的难点就是编译pysqlcipher3,为编译这个,搞了好几天,分别在三台电脑上测试通过(工作电脑+家用台式+家用笔记本),我已将编译好的【pysqlcipher3.zip+其它需要环境搭建的安装软件+项目测试】放在了最后的下载包中,你只需要安装软件,执行一个安装命令即可完成整个环境的搭建。(根据官网直接用pip install pysqlcipher3始终安装不起,只有自己动手下载源码编译安装了),本人使用环境是windows10专来版+python3.7版本(注意最好是python3.7,经测最新版python3.11编译不过,帮你们汤坑了,你不要再试python3.11了)
三、环搭搭建
1、Win64OpenSSL_Light-3_1_1.ms双击安装,不要修改配置,一路点确定
2、ActiveTcl-8.6.13.0000-MSWin32-x64-559160e0.msi 双击安装即可
3、配置C:\Program Files\OpenSSL-Win64\bin添加到系统环境变量path中,并添加一个新的环境变量OPENSSL_CONF为C:\Program Files\OpenSSL-Win64\openssl.cfg
修改环境变量方法,点击桌面【我的电脑】》【属性】》【高级系统设置】》【高级】》【环境变量】
4、vc_redist.x64.exe直接安装 (如果安装过更新版本则跳过)
5、打开https://visualstudio.microsoft.com/zh-hans/visual-cpp-build-tools/地址,【下载生成工具】,详见【下载Vc++工具.png】,安后安装
选择【使用C++的旧面开发】,注意右侧选择目录,详见【使用C++的卓面开发.png】,大约安装5分钟左右,看你网速、
6、安装时选【使用C++的桌面开发】,注意右侧选中项
说明,如果不安装【使用C++的桌面开发】,我遇到了【error: Microsoft Visual C++ 14.0 or greater is required. Get it with "Microsoft C++ Build Tools": https://visualstudio.microsoft.com/visual-cpp-build-tools/】,
【C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.16.27023\include】,【C:\Users\ASUS\Desktop\pysqlcipher3-1.0.3\pysqlcipher3-1.0.3\src\python3\connection.h(33): fatal error C1083: 无法打开包括文件: “sqlcipher/sqlite3.h”: No such file or directory
error: command 'C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\VC\\Tools\\MSVC\\14.21.27702\\bin\\HostX86\\x64\\cl.exe' failed with exit status 2】这个错误
只要安装了上面的【使用C++的桌面开发】,上面两个问题,就解决了
7、pysqlcipher3.zip解压到c盘根目录 目录结构 C:\pysqlcipher3,进入到目录执行python setup.py install这个命令,打印出“Finished processing dependencies for pysqlcipher3==1.0.2” 安装完成
8、生成的结果在【python安装环境\Lib\site-packages\pysqlcipher3-1.0.2-py3.7-win-amd64.egg】目录下的pysqlcipher3文件夹,
使用说明,将此包文件夹pysqlcipher3放在PyCharm软件对应工程的venv\Lib\site-packages目录下即可
四、项目测试
1、用pycharm打开工程pysqlcipher3-test截图如下
2、相关核心代码
import tkinter
from tkinter import messagebox
from common import Utils
from config import Constant
from config.SqlHelper import SqlHelper
from model.Models import User
class UserPage(object):
def __init__(self):
self.root = tkinter.Tk()
self.root.title("系统测试--")
Utils.set_screen(self.root, 850, 650)
self.page = tkinter.Frame(self.root, width=850, height=650)
self.page.pack(side='top')
self.user = User()
self.user.userId = tkinter.StringVar()
self.user.username = tkinter.StringVar()
self.user.phone = tkinter.StringVar()
self.msg = tkinter.StringVar()
self.userName_find = tkinter.StringVar()
self.userName_find.set('请输入用户名称')
tkinter.Label(self.page, text='用户名称:', font=('Terminal', 12)).grid(row=1, column=1)
tkinter.Entry(self.page, textvariable=self.user.username, width=20).grid(row=1, column=2, columnspan=2)
tkinter.Label(self.page, text='用户电话:', font=('Terminal', 12)).grid(row=2, column=1, )
tkinter.Entry(self.page, textvariable=self.user.phone, width=20).grid(row=2, column=2, columnspan=2)
tkinter.Button(self.page, text='保存', font=('Terminal', 12), command=self.save).grid(row=3, column=1,)
tkinter.Entry(self.page, textvariable=self.userName_find, width=20).grid(row=4, column=1, columnspan=2)
tkinter.Button(self.page, text='查询', font=('Terminal', 12), command=self.get_User).grid(row=5, column=2)
tkinter.Label(self.page, textvariable=self.msg, font=('Terminal', 12)).grid(row=5, column=1)
# 查询基础配置
def get_User(self):
session = SqlHelper().session
results = session.query(User).where(User.username==self.userName_find.get()).all()
string = ''
for row in results:
string = ' '+ '用户ID:' + str(row.userId) + ' 用户名称:' + row.username + ' 电话:' + row.phone
messagebox.showinfo('提示信息', string)
session.close()
def save(self):
sql_helper = SqlHelper()
saveUser = User()
saveUser.username = self.user.username.get();
saveUser.phone = self.user.phone.get()
sql_helper.update(saveUser)
messagebox.showinfo('提示信息','保存成功')
if __name__ == '__main__':
Utils.init_sys_user()
dbSetPage = UserPage()
dbSetPage.root.mainloop()
from sqlalchemy import create_engine, Connection, Engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker, scoped_session, Session
from config import Constant
class SessionManager(object):
def __init__(self, **kwargs):
self.engine: Engine = None
self.session: Session = None
self.db_type = None
self.kwargs = kwargs
def get_session(self, db_type=None) -> Session:
print('获取session,db_type:', db_type)
if self.db_type == db_type and self.session is not None:
return self.session
elif db_type == Constant.DB_TYPE_MYSQL:
self.remove_session()
self.engine = create_engine(Constant.MYSQL_URL, echo=True)
self.session = scoped_session(sessionmaker(bind=self.engine))
Base.metadata.create_all(self.engine)
else:
self.remove_session()
self.engine = create_engine(Constant.SQLITE_URL, echo=True)
self.session = sessionmaker(bind=self.engine)
Base.metadata.create_all(self.engine)
self.db_type = db_type
return self.session
def get_engine(self, db_type=None) -> Engine:
print('获取engine,db_type:', db_type)
self.get_session(db_type)
return self.engine
def remove_session(self):
if self.session is not None:
self.engine = None
self.session = None
sessionManager = SessionManager()
Base = declarative_base()
DB_TYPE_MYSQL = 'MYSQL'
DB_TYPE_SQLITE = 'SQLITE'
DB_TYPE = DB_TYPE_SQLITE # 当前数据类型
# SQLITE_URL = 'sqlite:///D:/dd/aippw.db3' #sqlite连接地址
SQLITE_URL = 'sqlite+pysqlcipher://:123123@/D:/dd/testdb.db3' #sqlite连接地址 123123为sqlite连接密码
3、运行main
4、运行main之后,在d:\dd\testdb.db3文件会自动生成,这个就是sqlite3数据库文件,连接密码为123123,然后安装DB.Browser.for.SQLite-3.12.2-win64.msi这个软件之后,桌面会有【DB Browser (SQLCipher)】这个文件,双打开
5、测试保存
6、测试查询
五、软件包下载
pysqlcipher3.zip+其它需要环境搭建的安装软件+项目测试,下载地址:链接:https://pan.baidu.com/s/1EXY4Mt_iKwmOpjU4saDK5Q?pwd=ptuw
提取码:ptuw