使用 Python和 SQLite 打造一个简单的数据库浏览器

news2024/11/14 12:01:37

在日常开发中,我们常常需要快速查看和操作SQLite数据库中的数据。虽然有许多现成的工具可以完成这一任务,但有时你可能想要一个更为简单、可定制的解决方案。在这篇博客中,我将带你一步步构建一个简单的SQLite数据库浏览器,它可以用来列出数据库中的表名、查看表的字段名、编写SQL语句并执行查询操作,并将结果展示在网格中。我们将使用 wxPython 来创建这个图形用户界面。
C:\pythoncode\new\sqliteanalysis.py

全部代码

import wx
import sqlite3
import wx.grid as gridlib

class SQLiteBrowser(wx.Frame):
    def __init__(self, *args, **kw):
        super(SQLiteBrowser, self).__init__(*args, **kw)

        self.InitUI()
        self.conn = None

    def InitUI(self):
        panel = wx.Panel(self)

        vbox = wx.BoxSizer(wx.VERTICAL)

        hbox1 = wx.BoxSizer(wx.HORIZONTAL)
        self.btn_open = wx.Button(panel, label="Open Database")
        self.btn_open.Bind(wx.EVT_BUTTON, self.OnOpen)
        hbox1.Add(self.btn_open, flag=wx.LEFT, border=10)
        vbox.Add(hbox1, flag=wx.EXPAND | wx.TOP | wx.BOTTOM, border=10)

        hbox2 = wx.BoxSizer(wx.HORIZONTAL)
        self.listbox1 = wx.ListBox(panel)
        self.listbox1.Bind(wx.EVT_LISTBOX, self.OnTableSelected)
        hbox2.Add(self.listbox1, proportion=1, flag=wx.EXPAND | wx.ALL, border=10)
        
        self.listbox2 = wx.ListBox(panel)
        self.listbox2.Bind(wx.EVT_LISTBOX, self.OnColumnSelected)
        hbox2.Add(self.listbox2, proportion=1, flag=wx.EXPAND | wx.ALL, border=10)

        vbox.Add(hbox2, proportion=1, flag=wx.EXPAND)

        hbox3 = wx.BoxSizer(wx.HORIZONTAL)
        self.text_ctrl = wx.TextCtrl(panel, style=wx.TE_MULTILINE)
        hbox3.Add(self.text_ctrl, proportion=1, flag=wx.EXPAND | wx.ALL, border=10)

        self.btn_exec = wx.Button(panel, label="Execute SQL")
        self.btn_exec.Bind(wx.EVT_BUTTON, self.OnExecuteSQL)
        hbox3.Add(self.btn_exec, flag=wx.LEFT, border=10)

        vbox.Add(hbox3, proportion=1, flag=wx.EXPAND)

        hbox4 = wx.BoxSizer(wx.HORIZONTAL)
        self.grid = gridlib.Grid(panel)
        self.grid.CreateGrid(5, 5)
        hbox4.Add(self.grid, proportion=1, flag=wx.EXPAND | wx.ALL, border=10)

        vbox.Add(hbox4, proportion=3, flag=wx.EXPAND)

        panel.SetSizer(vbox)
        self.SetTitle('SQLite Browser')
        self.Centre()

    def OnOpen(self, event):
        with wx.FileDialog(self, "Open SQLite file", wildcard="SQLite files (*.db)|*.db",
                           style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) as fileDialog:
            if fileDialog.ShowModal() == wx.ID_CANCEL:
                return

            path = fileDialog.GetPath()
            self.conn = sqlite3.connect(path)
            self.LoadTables()

    def LoadTables(self):
        if self.conn:
            cursor = self.conn.cursor()
            cursor.execute("SELECT name FROM sqlite_master WHERE type='table';")
            tables = [row[0] for row in cursor.fetchall()]
            self.listbox1.Set(tables)

    def OnTableSelected(self, event):
        table_name = self.listbox1.GetStringSelection()
        if self.conn:
            cursor = self.conn.cursor()
            cursor.execute(f"PRAGMA table_info({table_name})")
            columns = [row[1] for row in cursor.fetchall()]
            self.listbox2.Set(columns)

    def OnColumnSelected(self, event):
        column_name = self.listbox2.GetStringSelection()
        current_text = self.text_ctrl.GetValue()
        if current_text:
            current_text += f", {column_name}"
        else:
            current_text = column_name
        self.text_ctrl.SetValue(current_text)

    def OnExecuteSQL(self, event):
        sql_query = self.text_ctrl.GetValue()
        if self.conn and sql_query.strip():
            cursor = self.conn.cursor()
            try:
                cursor.execute(sql_query)
                results = cursor.fetchall()
                self.DisplayResults(results)
            except sqlite3.Error as e:
                wx.MessageBox(f"An error occurred: {e}", "Error", wx.OK | wx.ICON_ERROR)

    def DisplayResults(self, results):
        if results:
            rows = len(results)
            cols = len(results[0])
            self.grid.ClearGrid()
            if rows > self.grid.GetNumberRows():
                self.grid.AppendRows(rows - self.grid.GetNumberRows())
            if cols > self.grid.GetNumberCols():
                self.grid.AppendCols(cols - self.grid.GetNumberCols())

            for i, row in enumerate(results):
                for j, value in enumerate(row):
                    self.grid.SetCellValue(i, j, str(value))

if __name__ == '__main__':
    app = wx.App(False)
    frame = SQLiteBrowser(None)
    frame.Show(True)
    app.MainLoop()

环境准备

在开始之前,你需要确保已安装以下Python库:

  1. wxPython:用于创建桌面应用的GUI库。
  2. sqlite3:Python自带的SQLite接口模块,用于与SQLite数据库进行交互。

如果你尚未安装 wxPython,可以通过以下命令安装:

pip install wxPython

项目目标

我们将创建一个简单的应用程序,其主要功能包括:

  1. 选择SQLite数据库文件:通过文件选择对话框选择一个SQLite数据库文件,并与之建立连接。
  2. 列出表名:在左侧列表框中列出所选数据库的所有表名。
  3. 列出字段名:在中间列表框中列出所选表的所有字段名。
  4. 构建SQL查询:点击字段名,自动将其追加到查询输入框中。
  5. 执行SQL查询:点击执行按钮,运行输入框中的SQL查询语句,并将结果展示在网格中。

代码实现

以下是完整的Python代码,它实现了上述所有功能:

import wx
import sqlite3
import wx.grid as gridlib

class SQLiteBrowser(wx.Frame):
    def __init__(self, *args, **kw):
        super(SQLiteBrowser, self).__init__(*args, **kw)

        self.InitUI()
        self.conn = None

    def InitUI(self):
        panel = wx.Panel(self)

        vbox = wx.BoxSizer(wx.VERTICAL)

        hbox1 = wx.BoxSizer(wx.HORIZONTAL)
        self.btn_open = wx.Button(panel, label="Open Database")
        self.btn_open.Bind(wx.EVT_BUTTON, self.OnOpen)
        hbox1.Add(self.btn_open, flag=wx.LEFT, border=10)
        vbox.Add(hbox1, flag=wx.EXPAND | wx.TOP | wx.BOTTOM, border=10)

        hbox2 = wx.BoxSizer(wx.HORIZONTAL)
        self.listbox1 = wx.ListBox(panel)
        self.listbox1.Bind(wx.EVT_LISTBOX, self.OnTableSelected)
        hbox2.Add(self.listbox1, proportion=1, flag=wx.EXPAND | wx.ALL, border=10)
        
        self.listbox2 = wx.ListBox(panel)
        self.listbox2.Bind(wx.EVT_LISTBOX, self.OnColumnSelected)
        hbox2.Add(self.listbox2, proportion=1, flag=wx.EXPAND | wx.ALL, border=10)

        vbox.Add(hbox2, proportion=1, flag=wx.EXPAND)

        hbox3 = wx.BoxSizer(wx.HORIZONTAL)
        self.text_ctrl = wx.TextCtrl(panel, style=wx.TE_MULTILINE)
        hbox3.Add(self.text_ctrl, proportion=1, flag=wx.EXPAND | wx.ALL, border=10)

        self.btn_exec = wx.Button(panel, label="Execute SQL")
        self.btn_exec.Bind(wx.EVT_BUTTON, self.OnExecuteSQL)
        hbox3.Add(self.btn_exec, flag=wx.LEFT, border=10)

        vbox.Add(hbox3, proportion=1, flag=wx.EXPAND)

        hbox4 = wx.BoxSizer(wx.HORIZONTAL)
        self.grid = gridlib.Grid(panel)
        self.grid.CreateGrid(5, 5)
        hbox4.Add(self.grid, proportion=1, flag=wx.EXPAND | wx.ALL, border=10)

        vbox.Add(hbox4, proportion=3, flag=wx.EXPAND)

        panel.SetSizer(vbox)
        self.SetTitle('SQLite Browser')
        self.Centre()

    def OnOpen(self, event):
        with wx.FileDialog(self, "Open SQLite file", wildcard="SQLite files (*.db)|*.db",
                           style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) as fileDialog:
            if fileDialog.ShowModal() == wx.ID_CANCEL:
                return

            path = fileDialog.GetPath()
            self.conn = sqlite3.connect(path)
            self.LoadTables()

    def LoadTables(self):
        if self.conn:
            cursor = self.conn.cursor()
            cursor.execute("SELECT name FROM sqlite_master WHERE type='table';")
            tables = [row[0] for row in cursor.fetchall()]
            self.listbox1.Set(tables)

    def OnTableSelected(self, event):
        table_name = self.listbox1.GetStringSelection()
        if self.conn:
            cursor = self.conn.cursor()
            cursor.execute(f"PRAGMA table_info({table_name})")
            columns = [row[1] for row in cursor.fetchall()]
            self.listbox2.Set(columns)

    def OnColumnSelected(self, event):
        column_name = self.listbox2.GetStringSelection()
        current_text = self.text_ctrl.GetValue()
        if current_text:
            current_text += f", {column_name}"
        else:
            current_text = column_name
        self.text_ctrl.SetValue(current_text)

    def OnExecuteSQL(self, event):
        sql_query = self.text_ctrl.GetValue()
        if self.conn and sql_query.strip():
            cursor = self.conn.cursor()
            try:
                cursor.execute(sql_query)
                results = cursor.fetchall()
                self.DisplayResults(results)
            except sqlite3.Error as e:
                wx.MessageBox(f"An error occurred: {e}", "Error", wx.OK | wx.ICON_ERROR)

    def DisplayResults(self, results):
        if results:
            rows = len(results)
            cols = len(results[0])
            self.grid.ClearGrid()
            if rows > self.grid.GetNumberRows():
                self.grid.AppendRows(rows - self.grid.GetNumberRows())
            if cols > self.grid.GetNumberCols():
                self.grid.AppendCols(cols - self.grid.GetNumberCols())

            for i, row in enumerate(results):
                for j, value in enumerate(row):
                    self.grid.SetCellValue(i, j, str(value))

if __name__ == '__main__':
    app = wx.App(False)
    frame = SQLiteBrowser(None)
    frame.Show(True)
    app.MainLoop()

代码讲解

1. 打开数据库
def OnOpen(self, event):
    with wx.FileDialog(self, "Open SQLite file", wildcard="SQLite files (*.db)|*.db",
                       style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) as fileDialog:
        if fileDialog.ShowModal() == wx.ID_CANCEL:
            return

        path = fileDialog.GetPath()
        self.conn = sqlite3.connect(path)
        self.LoadTables()

这里,我们使用 wx.FileDialog 来打开文件选择对话框。用户选择一个SQLite数据库文件后,我们使用 sqlite3.connect() 方法建立数据库连接,并调用 LoadTables 方法列出所有表名。

2. 列出表名和字段名
def LoadTables(self):
    if self.conn:
        cursor = self.conn.cursor()
        cursor.execute("SELECT name FROM sqlite_master WHERE type='table';")
        tables = [row[0] for row in cursor.fetchall()]
        self.listbox1.Set(tables)

LoadTables 方法通过执行 SELECT name FROM sqlite_master WHERE type='table'; 查询来获取所有表名,并将其添加到左侧的 ListBox 中。

def OnTableSelected(self, event):
    table_name = self.listbox1.GetStringSelection()
    if self.conn:
        cursor = self.conn.cursor()
        cursor.execute(f"PRAGMA table_info({table_name})")
        columns = [row[1] for row in cursor.fetchall()]
        self.listbox2.Set(columns)

当用户点击某个表名时,OnTableSelected 方法会被调用,它使用 PRAGMA table_info(table_name) 查询该表的所有字段名,并将其显示在中间的 ListBox 中。

3. 构建和执行SQL查询
def OnColumnSelected(self, event):
    column_name = self.listbox2.GetStringSelection()
    current_text = self.text_ctrl.GetValue()
    if current_text:
        current_text += f", {column_name}"
    else:
        current_text = column_name
    self.text_ctrl.SetValue(current_text)

用户点击字段名时,OnColumnSelected 方法会将字段名追加到右侧的SQL输入框中,帮助用户快速构建SQL查询语句。

def OnExecuteSQL(self, event):
    sql_query = self.text_ctrl.GetValue()
    if self.conn and sql_query.strip():
        cursor = self.conn.cursor()
        try:
            cursor.execute(sql_query)
            results = cursor.fetchall()
            self.DisplayResults(results)
        except sqlite3.Error as e:
            wx.MessageBox(f"An error occurred: {e}", "Error", wx.OK | wx.ICON_ERROR)

点击“Execute SQL”按钮后,OnExecuteSQL 方法将执行输入框中的SQL语句,并调用 DisplayResults 方法将查询结果展示在网格里。

4. 显示查询结果
def DisplayResults(self, results):
    if results:
        rows = len(results)
        cols = len(results[0])
        self.grid.ClearGrid()
        if rows > self.grid.GetNumberRows():
            self.grid.AppendRows(rows - self.grid.GetNumberRows())
        if cols > self.grid.GetNumberCols():
            self.grid.AppendCols(cols - self.grid.GetNumberCols())

        for i, row in enumerate(results):
            for j, value in enumerate(row):
                self.grid.SetCellValue(i, j, str(value))

DisplayResults 方法会根据查询结果动态调整网格的大小,并将查询结果逐个填充到网格中。

结果如下

在这里插入图片描述

结语

通过上述代码,我们已经成功创建了一个简单的SQLite数据库浏览器,它可以帮助你快速查看和操作数据库中的数据。这个项目非常适合用作学习 wxPythonsqlite3 的入门项目,你可以在此基础上进一步扩展功能,如支持更多的SQL操作、增加数据编辑功能、或改进用户界面。

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

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

相关文章

怎么将文档翻译英文?多语言翻译的4个方法

当你准备将文档翻译成英文并发送给海外客户时,你可能会同时感到兴奋和焦虑。 兴奋的原因是,你的业务即将扩展到全球市场;焦虑的原因是,如果翻译出现错误,可能会造成尴尬的局面。 不过,不必过于担心。今天…

高速信号的眼图、加重、均衡

目录 高速信号的眼图、加重、均衡眼图加重均衡线性均衡器CTLE判决反馈均衡器DFE 高速信号的眼图、加重、均衡 眼图 通常用示波器观察接收信号波形的眼图来分析码间串扰和噪声对系统性能的影响,从而估计系统优劣程度,因而眼图分析是高速互连系统信号完整…

电信天翼网关TEWA-1000E/G等系列光猫新版固件破解超级密码

实际操作机型TEWA-1006G,参考教程电信天翼网关TEWA-1000E/G等系列光猫破解超级密码。 之前,在同一个光猫上使用上述教程成功拿到了超级密码,但是一年之后电信远程更新了固件,该破解方法部分失效,于是我在研究之后找到了…

2024开源资产管理系统推荐 8款免费开源IT资产管理系统/软件

开源资产管理系统 开源资产管理系统是帮助企业管理、跟踪和优化其资产的强大工具。这些系统能够自动记录资产的详细信息,如采购日期、使用情况、维护记录等,从而实现资产的全生命周期管理。企业可以通过这些系统优化资产使用效率,减少资产闲…

8月15日笔记

masscan安装使用 首先需要有c编译器环境。查看是否有c编译器环境: gcc -v如果系统中已经安装了 GCC,这个命令将输出 GCC 的版本信息。如果未安装,你会看到类似于 “command not found” 的错误消息。 如果没有下载,使用如下命令…

SAP中如何导出物料的评估类清单?

接到内部产品控制同事请求,希望从系统中帮忙导出物料的评估类清单。查询到评估类对应的数据表是T025。通过SE16可以查询和输出。 输入查询条件后,在出现的清单中输出到本地文件,存储成excel文件后发给用户,任务完成。 这样就可以导…

掌握内网渗透之道,成为实战高手,看《内网渗透实战攻略》就够了

【文末送书】【文末送书】今天推荐一本网络安全领域优质书籍《内网渗透实战攻略》 文章目录 * 前言如何阅读本书目录文末送书 前言 ![在这里插入图片描述](https://img- blog.csdnimg.cn/direct/fd88c968fc5349aea8945ee5345d6881.jpeg) 当今,网络系统面临着越…

【MMdetection改进】换遍MMDET主干网络之SwinTransformer-Tiny(基于MMdetection)

OpenMMLab 2.0 体系中 MMYOLO、MMDetection、MMClassification、MMSelfsup 中的模型注册表都继承自 MMEngine 中的根注册表,允许这些 OpenMMLab 开源库直接使用彼此已经实现的模块。 因此用户可以在MMYOLO 中使用来自 MMDetection、MMClassification、MMSelfsup 的主…

AI作画提示词(Prompts)工程:技巧与最佳实践

GPT-4o (OpenAI) AI 作画提示词(prompts)工程可以极大地提高生成图像的质量和细节表现。以下是一些技巧和最佳实践,以帮助你优化提示词的使用: 一、明确的描述 1. 具体化:明确描述你想要的元素和风格。例如&#xff0…

机器视觉28

1.CPK(制程能力指数)用于衡量生产过程的稳定性和能力,评估产品规格的一致性。 2.CPK的值是根据具体的产品规格、生产过程数据以及统计分析得出。 3.CPK的值越高,表示制程能力越强,产品规格的一致性越好。 CPK与不良…

【网络】【Linux】Linux内核中连接的组织形式与全连接队列

Linux内核中连接的组织形式与全连接队列 文章目录 1.前言2.Linux内核中连接的组织形式2.1套接字和文件描述符2.2创建连接 & 获取连接 3.全连接队列3.1为什么有全连接队列?3.2全连接队列的长度 1.前言 TCP是面向连接的,TCP的各种可靠性机制实际都不…

c++中的引用()及做返回值问题

传值返回: int Count1() {int n 0;n;return n; } int main() {int& r1 Count1();return 0; } 总结:返回局部变量的引用是不安全的。 static int cab; 只有第一次定义c时才会执行 要想给变c的值应 static int c1; cab; 传值、传引用效率比较 #…

【抓包】- Fiddler抓包教程,使用Fiddle抓取B站视频;ffmpeg的使用方法

一、预准备:过滤器设置 打开fiddler后,清空内容,然后播放视频。 找到与B站视频资源相关的回应,而后在“原始(raw)”标签中查看它的host信息。 发现B站视频资源的服务器DNS地址为【*bilivideo.cn】、【*bi…

超越GPT-4 ,金融分析新突破:FinTral多模态大模型

人工智能咨询培训老师叶梓 转载标明出处 在金融领域,对大量非结构化数据的处理和分析一直是行业面临的重要挑战。为了解决这一问题,由不列颠哥伦比亚大学和Invertible AI的研究团队共同提出了一套名为FinTral的先进多模态大模型(LLMs&#xf…

云计算实训26——部署LVS负载均衡项目(上)

LVS LVS是linux virtural server的简称——免费、开源、四层负载均衡 工作原理: 通过linux达到负载均衡好和linux操作系统实现高性能高可用的linux服务集群,具有良好的可靠性、可扩展性、可操作性、可扩展性、从而实现以低廉的成本实现最优的性能。LV…

前端案例:Alloy Team|腾讯全端项目(响应式)

前言 这是一个简单的响应式项目,模仿了Alloy Team|腾讯全端部分内容,模拟了可以适应不同类型的设备 项目总览 整体布局 屏幕大于1200px概况: 头部标签hover 轮播图 屏幕在小于992px概况 头部背景变色 固定 屏幕在小于992px概况 屏幕大于7…

基于YOLOv8的手部检测(1)- 手部数据集获取(数据集下载、数据清洗、处理与增强)

前言 在进行手部姿态估计、手势识别时,需要先检测出手的位置。本文对网上公开的手部数据集进行获取、清洗、处理与数据增强,用于YOLO等目标检测网络的训练。 1.手部检测数据集概览 1.1 HaGRID手势识别数据集 项目地址: https://github.com/…

[C++] STL (multi)map/(multi)set简介

标题:[C] STL (multi)map/(multi)set简介 水墨不写bug 目录 前言: 一、set简介 1.set简介 2.set的常见用法 二、map简介 1.map简介 2.map使用 三、multiset简介 1.multiset简介 2.multiset使用 四、multimap简介 1.multimap简介 2.multim…

DVWA-IDS测试(特殊版本)

起因 浏览DVWA历史更新记录发现有版本带有IDS插件,可以用于平时没有相关设备等场景演示用,所以开启本次测试。 下载 官方最新版本是移除了IDS插件,原因是“从不使用”,所以需要下载移除该插件之前的版本。 https://github.com/…