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

news2024/11/19 2:03:20
一、背景

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/699730.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Spring Boot 中的 Environment

Spring Boot 中的 Environment 在 Spring Boot 中,Environment 是一个重要的组件,用于管理应用程序的配置。它是一个接口,提供了访问应用程序配置属性的方法。在本文中,我们将深入探讨 Spring Boot 中的 Environment,…

Git基本操作总结

0.Git操作关系图 1.初次创建仓库 1)git ini(初次提交时使用,项目中会生成.git文件) 2)git add . 3)git commit -m “提交代码” 4)git remote add origin “http://xxx.git”(关联远程主机) / git remote rm origin …

服务器数据恢复-NetApp FAS存储误删文件夹的数据恢复案例

NetApp存储故障&分析: 某公司一台NetApp存储,工作人员误操作删除一个重要的文件夹。 虽然被删除已经有一段时间了,但是根据NetApp文件系统WAFL的特点,数据被覆盖的可能性不大。 NetApp存储数据恢复过程: 1、由于不…

自学黑客(网络安全),一般人我劝你还是算了吧(自学网络安全学习路线--第二十章 欺骗攻击及防御技术上)【建议收藏】

文章目录 一、自学网络安全学习的误区和陷阱二、学习网络安全的一些前期准备三、自学网络安全学习路线一、概述二、IP欺骗及防御技术1、基本的IP欺骗2、源路由攻击3、IP欺骗的高级应用——TCP会话劫持4、TCP三步握手连接建立5、TCP会话劫持过程6、IP欺骗攻击的防御7、防范源路由…

【实用工具】MapStruct—性能无限接近原生手写的对象转换工具

文章目录 优秀借鉴 1、引入2、什么是MapStruct2.1、概述2.2、横向对比2.3、优势 3、快速入门3.1、Maven3.2、POJO3.3、统一映射接口3.4、业务映射接口3.5、测试3.6、输出 4、简单分析5、拓展使用 优秀借鉴 What is a Data Transfer Object (DTO)?Java bean mappings, the easy…

多元回归预测 | Matlab北方苍鹰算法(NGO)优化极限学习机ELM回归预测,NGO-ELM回归预测,多变量输入模型

文章目录 效果一览文章概述部分源码参考资料效果一览 文章概述 多元回归预测 | Matlab北方苍鹰算法(NGO)优化极限学习机ELM回归预测,NGO-ELM回归预测,多变量输入模型 评价指标包括:MAE、RMSE和R2等,代码质量极高,方便学习和替换数据。要求2018版本及以上。 部分源码 %% 清…

HTTP模式下STM32程序远程升级设计

针对嵌入式终端设备架设分散、数量庞大以及应用程序更新迭代速度快带来的程序升级困难局面,运用STM32微控制器的在应用中编程(IAP)原理,设计了通过以太网远程升级程序的方案。 HTTP协议和LwIP协议的使用,不仅让整个方…

安装mmdetection2.22(windows下)

安装mmdetection2.22 确定版本安装mmcv1.4安装mmdetection测试方案1方案2 确定版本 安装mmcv1.4 首先.cuda,pytorch得安装好,这里我拷贝pt1.8虚拟环境 安装mmcv1.4 安装mmdetection 参考文章 下载 cd E:\Code\mmdetection\mmdetection-2.22.0 pip install -r…

机械臂笛卡尔空间轨迹规划

目录 1 引言 2 任务位置规划 2.1直线轨迹规划 2.2圆弧轨迹规划 (1)进行第一个步骤: (2) 进行第二步骤: (3)进行第三个步骤: (4)进行第四个步骤: 1 引言 随着6R机械人的使用…

设备通过ehome接入到EasyCVR后,通道数量显示不全是什么原因?

EasyCVR可拓展性强、视频能力灵活、部署轻快,可支持的主流标准协议有GB28181、RTSP/Onvif、RTMP等,以及厂家私有协议与SDK接入,包括海康Ehome、海大宇等设备的SDK等,能对外分发RTSP、RTMP、FLV、HLS、WebRTC等格式的视频流。 有用…

【LeetCode】HOT 100(19)

题单介绍: 精选 100 道力扣(LeetCode)上最热门的题目,适合初识算法与数据结构的新手和想要在短时间内高效提升的人,熟练掌握这 100 道题,你就已经具备了在代码世界通行的基本能力。 目录 题单介绍&#…

linux修改oracle sys密码

忘记了sys密码 su - oracle; sqlplus / as sysdba; alter user system identified by test; navicat测试连接

【软件测试三】测试用例篇

目录 1.测试用例的基本要素 2.测试用例的给我们带来的好处 3.设计测试用例的万能公式 3.1.水杯的测试用例 3.2.微信发送朋友圈的测试用例 4.设计测试用例的方法 基于需求设计的测试用例 1.等价类 2.边界值 3.判定表 4.正交法 1.正交表表达式 2.特点: …

【OSI体系结构】网络杂谈(14)之OSI体系结构精准理解

涉及知识点 什么是OSI体系结构,OSI体系结构的概念,网络协议三要素,应用层,表示层,会话层,传输层,表示层,数据链路层,物理层,开放系统互连参考模型各层的功能…

CRM系统助力医疗机构数字化营销全链路,让获客和留存更简单

在数字经济背景下,医疗行业面临经营、管理、组织变革升级的迫切需求。伴随云计算、大数据、物联网、5G、人工智能等数字化技术的创新应用,加速推动了国内医疗机构数字化转型地落地。后疫情时代下,如何展望未来、寻找医疗健康行业重回增长轨道…

原生DOM与组件绑定 原生DOM事件和自定义事件

1. 原生DOM可以绑定原生DOM系统事件 2. 组件标签可以绑定系统事件(不起作用,因为属于自定义事件)------ .native (可以把自定义事件变为原生DOM事件) 3. 原生DOM绑定自定义事件 ---无意义:因为没有办法触…

企业部署MES管理系统需要配置专业团队吗

随着数字化转型的推进,越来越多的企业开始考虑部署MES生产管理系统来提高生产效率和管理水平。在部署制造企业MES系统时,是否需要配置专业团队是一个关键问题。本文将探讨企业部署MES管理系统所需的专业团队的重要性,并提供一些建议。 全球制…

微服务进阶篇

文章目录 1、SpringCloud面试快速答法 1.1、Eureka1.2、Nacos面试快速答法 1.3、Ribbon负载小总结面试快速答法 1.4、服务雪崩小总结面试快速答法 1.5、服务监控小总结面试快速答法 2、业务相关2.1、限流Nginx限流网关限流小总结面试快速答法 2.2、分布式事务分布式理论CAP、BA…

WEB漏洞-XXEXML之利用检测绕过全解(39)

#概念 xml:xml被设计成传输和储存数据,XML文档结构包括XML声明、DTD文档类型定义(可选)、文档元素,其焦点是数据的内容。就类似于一种数据的格式,代码类的一些东西; xxe:是xml上面的一个漏洞,…

STM32F407 基本定时器配置输出PWM方波

介绍STM32F407定时器PWM波形输出配置方式。 通过逻辑分析采集波形数据进行可视化显示对比。 【1】定时器PWM功能介绍 STM32F4 的定时器除了 TIM6 和 7。其他的定时器都可以用来产生 PWM 输出。其中高级定时器 TIM1 和 TIM8 可以同时产生多达 7 路的 PWM 输出。而通用定时器也…