使用python3的sqlalchemy+sqlcipher3对sqlite3数据加密,使用pysqlcipher3编译打建环境,并写项目测试

一、背景

最近有个想法,想写一个软件,前期本来想用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了)

三、环搭搭建

说明,如果直接使用编译好的包,第7、8步骤就可以不做了,直接跳过

1、复制OpenSSL-Win64(在安装软件文件夹下)到C盘

2、配置C:\OpenSSL-Win64\bin添加到系统环境变量path中,并添加一个新的环境变量OPENSSL_CONF为C:\OpenSSL-Win64\bin\openssl.cfg
   修改环境变量方法,点击桌面【我的电脑】》【属性】》【高级系统设置】》【高级】》【环境变量】

3、ActiveTcl-8.6.13.0000-MSWin32-x64-559160e0.msi 双击安装即可 

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

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值