当前位置:首页 » tkinter » 正文

tkinter之SQLite操作

这篇文章我来讲一下python内置的数据库sqlite3,这本是python知识,我们先是温习一下sqlite3知识,然后结果上一篇文章讲解的treeview组件或别的组件来显示数据库的增,查,改,删等操作结果。

先复习sqlite数据库知识。

1. 创建数据库文件

2. 操作SQLite: 增加记录,查看记录,修改记录,删除记录

 

对于SQLite操作的步骤:

1. 导入sqlite3模块

2. 创建Connection连接对象

3. 创建Cursor游标对象

4. 执行SQL语句,操作数据库的增,查,改,删等操作

5. 关闭游标对象

6. 增,查,改,删操作要提交事务

7. 关闭连接对象

 

好,先来创建一个数据库test1.db,并新建一个表user,表里有设2个字段:id,name,id设为主键,id字段属性为整型,占10个字节,name字段为字符型,占20个字节。下面的代码实现了以上功能:

 

创建数据库及创建一个数据表user

import sqlite3  # 导入sqlite3模块
 
# 创建连接对象
conn=sqlite3.connect('test1.db') #创建或打开数据库
 
# 创建游标对象
cur=conn.cursor() # 创建游标对象
 
# SQL语句
cur.execute('create table user (id int(10) primary key, name varchar(20))') 
# 创建表:user,2个字段:id,name,id为主键
 
# 关闭游标对象
cur.close()
 
# 提交事务
# --- 数据库的增,改,删要提交事务
 
# 关闭连接对象
conn.close()


运行后,就在你的代码目录里生成test1.db , 里面有一个表user,大家可以用Navicat for SQLite 等相关软件查看这个数据库里的user表是否生成。

 

如果你再次运行上面的代码,会出错,因为user表已经生成,不能再生成了。

好,我就在这个表的基础上,进行增加,查找,修改,删除的操作。

 

先增加几条记录,增加记录,也是操作SQL操作。操作数据库的步骤就像我前面说的几个步骤。

下面的代码会增加一条记录:1,‘刘一’

 

数据表增加一条记录:

import sqlite3  # 导入sqlite3模块
 
# 创建连接对象
conn=sqlite3.connect('test1.db') #创建或打开数据库
 
# 创建游标对象
cur=conn.cursor() # 创建游标对象
 
# SQL语句  # 源码来自wb98.com
# cur.execute("insert into user (id,name) values (1,'刘一')")
# 为了sql注入,不推荐上面这种方式
cur.execute('insert into user (id,name) values (?,?)',(1,'刘一'))
# 表user增加一条记录
 
# 关闭游标对象
cur.close()
 
# 提交事务
conn.commit() # 提交事务
# --- 数据库的增,改,删要提交事务
 
# 关闭连接对象
conn.close()


运行后,user表会增加一条记录。

注意,在sql语句中,为了防止sql注入风险,采用采用占用符的方式。

 

以上采用的是游标对象的execute方法新增一条记录,下代码采用executemany() 一次就新增几条记录,只要稍稍改动上面的代码就行了。    丶丌皛

 

数据表记录批量增加:

import sqlite3  # 导入sqlite3模块
 
# 创建连接对象
conn=sqlite3.connect('test1.db') #创建或打开数据库
 
# 创建游标对象
cur=conn.cursor() # 创建游标对象
 
# SQL语句
newlist=[(2,'陈二'),(3,'张三'),(4,'李四'),(5,'王五'),(6,'赵六'),
   (7,'孙七'),(8,'周八'),(9,'吴九'),(10,'郑十')]
cur.executemany('insert into user (id,name) values (?,?)',newlist)
# 表user批量增加几条记录
 
# 关闭游标对象
cur.close()
 
# 提交事务
conn.commit() # 提交事务
# --- 数据库的增,改,删要提交事务
 
# 关闭连接对象
conn.close()

以上代码,我在win10,python3.8版测试成功,Navicat for SQLite都可以打开数据库查看证实成功,但是我们现在要自己写代码输出这个数据库的内容。

  

数据表中的记录查看:

游标对象有几个方法跟记录查看有关,我们来学习或回顾一下:

方法

说明

fetchone()

获取查询结果集中的下一行,返回一个单一的序列,当没有数据时,返回 None

fetchmany(size)

获取查询结果集中的下一行组,返回一个列表。当没有更多的可用的行时,则返回一个空的列表。

fetchall()

获取查询结果集中所有(剩余)的行,返回一个列表。当没有可用的行时,则返回一个空的列表

 

下面的代码演示了上述3个方法:

import sqlite3  # 导入sqlite3模块
 
# 创建连接对象
conn=sqlite3.connect('test1.db') #创建或打开数据库
 
# 创建游标对象
cur=conn.cursor() # 创建游标对象
 
# SQL语句
cur.execute('select * from user where id=?',(1,)) #  查询第一条记录
result1=cur.fetchone() # 获取一条查询记录
print('第1条记录:',result1)
print('-----')
 
cur.execute('select * from user where id between ? and ?',(1,5)) # 查询id值范围为1-5之间的记录
result2=cur.fetchmany(5) # 获取5条查询记录
print('id=1至5的记录:',result2)
print('-----')
 
cur.execute('select * from user') # 查询所有记录
result3=cur.fetchall() # 获取所有的查询记录
print('所有的记录:',result3)
print('-----')
 
# 关闭游标对象
cur.close()
 
# 提交事务
conn.commit() # 提交事务
# --- 数据库的增,改,删要提交事务
 
# 关闭连接对象
conn.close()

运行代码,输出:

第1条记录: (1, '刘一')

-----

id=1至5的记录: [(1, '刘一'), (2, '陈二'), (3, '张三'), (4, '李四'), (5, '王五')]

-----

所有的记录: [(3, '张三'), (4, '李四'), (5, '王五'), (6, '赵六'), (7, '孙七'), (8, '周八'), (9, '吴九'), (10, '郑十')]

-----

 

数据库的记录修改:

数据表中的记录修改,我们也是通过execute()方法来操作sql语句来达成目的。下面的代码来演示一下,把第一条记录的name改成“曹操”。

import sqlite3  # 导入sqlite3模块
 
# 创建连接对象
conn=sqlite3.connect('test1.db') #创建或打开数据库
 
# 创建游标对象
cur=conn.cursor() # 创建游标对象
 
# SQL语句
cur.execute('update user set name=? where id=?',('曹操','1'))
# 修改id=1的记录 name='曹操'
 
# 关闭游标对象
cur.close()
 
# 提交事务
conn.commit() # 提交事务
# --- 数据库的增,改,删要提交事务
 
# 关闭连接对象
conn.close()


 数据表中的记录删除:

记录的删除,当然也是通过execute()方法来操作sql语句来达成目的。只要把上面的SQL语句改一下就行,其它都不用改变。

import sqlite3  # 导入sqlite3模块
 
# 创建连接对象
conn=sqlite3.connect('test1.db') #创建或打开数据库
 
# 创建游标对象
cur=conn.cursor() # 创建游标对象
 
# SQL语句
cur.execute('delete from user where id=?',(10,))
# 删除id=10的记录
 
# 关闭游标对象
cur.close()
 
# 提交事务
conn.commit() # 提交事务
# --- 数据库的增,改,删要提交事务
 
# 关闭连接对象
conn.close()

小醒一下:数据库的记录的增加,修改,删除要提交事务才可以更新成功。   丶丌皛

 

       上面是对SQLite3操作的基本知识的学习或回顾,下面我们要利用tkinter学习的组件知识来显示对数据库的操作结果。

Treeview组件用来显示数据表是非常合适的,下面就来讲一下如何显示数据表中的记录。

  

下面代码,是在上面的代码基础上,再加入创建一个treeview组件,用循环的方法,将fetchall() 返回的所有记录列表中的元素,一一插入到treeview组件里。这个难度并不大。

from tkinter import *
from tkinter.ttk import *
import sqlite3 # 导入sqlite3模块
 
root=Tk() # 源码来自wb98.com
 
# 创建连接对象
conn=sqlite3.connect('test1.db') #创建或打开数据库
 
# 创建游标对象
cur=conn.cursor() # 创建游标对象
 
# SQL语句
cur.execute('select * from user')
result=cur.fetchall() # 返回所有记录列表
 
# 关闭游标对象
cur.close()
 
# 提交事务
# --- 只是查询,不用提交事务
 
# 关闭连接对象
conn.close()
 
tree1=Treeview(root,columns=('c1','c2'),show='headings') # 创建无图标栏的单列表栏
tree1.column('#1',width=80,anchor=CENTER) # 设置组件标题栏宽度,列对齐方式
tree1.column('#2',width=80,anchor=CENTER)
tree1.heading('c1',text='ID') # 设置组件标题栏文本
tree1.heading('c2',text='姓名')
 
for i in result: # 循环把列表元素一一加入tree1组件
    tree1.insert('',index=END,values=i)
 
tree1.pack()
 
root.mainloop()

运行结果

             1.PNG

  

上面的数据库稍简单一点,不好演示SQL语句,我用代码,由一个文本导入到数据库。

先在test1.db这个数据库,再新建一个表student,然后用行方法读取文本db.txt,把一行作为一行记录读取到student表中。

下面是db.txt的内容:

1,a,3,李明,88,79,67,

2,b,5,王小梅,56,99,87,

3,a,2,陈小明,68,77,56,

4,b,6,张梅芳,74,86,76,

5,a,10,郑明,66,68,100,

6,b,8,何振华,77,87,91,

7,a,11,吴小芳,97,72,67,

8,b,1,姚明,68,77,87,

9,a,12,孙文正,89,81,73,

10,b,4,陈生国,50,86,93,

11,a,1,何云峰,88,99,96,

12,a,13,李强民,77,49,89,

13,a,4,明正,72,89,67,

14,b,3,曾红梅,48,55,86,

15,a,8,吴小京,82,67,69,

16,a,6,黄杰伦,75,74,96,

17,b,9,周春雨,95,65,99,

18,b,10,胡歌,91,99,67,

19,a,5,何英杰,89,85,91,

20,b,7,孙娜娜,79,83,99,

21,b,11,陈清锋,89,94,88,

22,a,9,李强,68,69,66,

23,b,2,何雨琴,67,93,67,

24,b,12,陈克民,98,67,56,

25,a,7,杨明明,46,100,87,

26,b,13,周玉琴,75,45,88,

 

 以下是新建数据表 student 的代码

import sqlite3  # 导入sqlite3模块
 
# 创建连接对象
conn=sqlite3.connect('test1.db') #创建或打开数据库
 
# 创建游标对象
cur=conn.cursor() # 创建游标对象
 
# SQL语句
cur.execute('''create table student (
   id INTEGER(10) primary key, 
   bj TEXT(10),
   xh TEXT(10),
   xm TEXT(10),
   yw REAL(10),
   sx REAL(10),
   yy REAL(10)
   )''') 
# 创建表student: id  bj班级 xh学号 xm姓名 yw语文 sx数学 yy英语
 
# 关闭游标对象
cur.close()
 
# 提交事务
# --- 数据库的增,改,删要提交事务
 
# 关闭连接对象
conn.close()

 

写代码把db.txt的文本导入到数据表student中

import sqlite3  # 导入sqlite3模块
 
with open('db.txt', 'r', encoding='utf-8') as file:  # 只读方式打开编码为utf-8的文本文件
    line = file.readlines()  # 以读取一行为列表方法读取全部行,line为分解好的列表内容
 
# str1[0]:id  str1[1]:bj班级  str1[2]:xh学号  str1[3]:xm姓名  str1[4]:yw语文
# str1[5]:sx数学  str1[6]:yy英语
 
# 创建连接对象
conn=sqlite3.connect('test1.db') #创建或打开数据库
 
# 创建游标对象
cur=conn.cursor() # 创建游标对象
 
for i in range(len(line)): # 以循环方法把读取的每一行插入到数据表的记录中
    str1 = line[i].split(',')  # 读取新一行记录
    cur.execute('insert into student (id,bj,xh,xm,yw,sx,yy) values (?,?,?,?,?,?,?)',str1)
 
# 关闭游标对象
cur.close()
 
# 提交事务
conn.commit() # 提交事务
# --- 数据库的增,改,删要提交事务
 
# 关闭连接对象
conn.close()

 

运行后,用Navicat for SQLite 查看test1中数据表student的结果

2.PNG

 

我就用这个数据表的数据来演示,用treeview等组件来显示数据,并顺便温习一下SQL语句知识。

以下是全部代码:

from tkinter import *
from tkinter.ttk import *
import sqlite3 # 导入sqlite3模块
 
def selectjob(strSQL):
    # 创建连接对象
    conn=sqlite3.connect('test1.db') # 创建或打开数据库
 
    # 创建游标对象
    cur=conn.cursor() # 创建游标对象
 
    for i in tree1.get_children(): # 清空treeview所有记录
        tree1.delete(i)
 
    # SQL语句
    cur.execute(strSQL)
 
    result=cur.fetchall() # 返回所有记录列表
 
    root.title(str(len(result))+"条记录")
 
    for i in result: # 循环把列表元素一一加入tree1组件
        tree1.insert('',index=END,values=i)
 
    # 关闭游标对象
    cur.close()
 
    # 提交事务
    # --- 只是查询,不用提交事务
 
    # 关闭连接对象
    conn.close()
 
root=Tk()
 
tree1=Treeview(root,columns=('c1','c2','c3','c4','c5','c6','c7'),show='headings') # 创建无图标栏的单列表栏
tree1.column('#1',width=40) # 设置组件标题栏宽度,列对齐方式
tree1.column('#2',width=40)
tree1.column('#3',width=40)
tree1.column('#4',width=80)
tree1.column('#5',width=80)
tree1.column('#6',width=80)
tree1.column('#7',width=80)
 
tree1.heading('c1',text='ID') # 设置组件标题栏文本
tree1.heading('c2',text='班级')
tree1.heading('c3',text='学号')
tree1.heading('c4',text='姓名')
tree1.heading('c5',text='语文')
tree1.heading('c6',text='数学')
tree1.heading('c7',text='英文')
 
root.rowconfigure(0,weight=1) # 某行 限制最小高度为30像素
root.columnconfigure(0,weight=1) # 某列 限制最小宽度为66像素
root.columnconfigure(1,weight=1) # 某列 限制最小宽度为66像素
root.columnconfigure(2,weight=1) # 某列 限制最小宽度为66像素
 
tree1.grid(row=0,column=0,columnspan=3,sticky=NSEW)
 
scr1=Scrollbar(root)  # 垂直滚动条
scr1.grid(row=0,column=3,sticky=N+S)
 
tree1.config(yscrollcommand = scr1.set) # Treeview和滚动条互相绑定
scr1.config(command = tree1.yview)
 
var=StringVar()
list1=('显示所有同学',
       '只显示a班同学',
       '姓名含“明”字的同学',
       '姓名第2个字是“明”的同学',
       '二字姓名,第2个字是“明”的同学',
       '3门功课有一门为100分的同学',
       '3门功课都不及格的同学',
       '学号为1,5,7,8的同学',
       '三门功课平均分>=90分的同学',
       'a班按语文成绩降序排列,辅之以数学降序,英文升序排列',
       '名字不包含“雨”字的同学',
       '语文分数在90到100之间高分同学',
       '语文分数在60到90分范围以外的高分和低分同学,降序排列',
       '姓名第2字和第3字相同的姓名',
       '显示姓“郑,何,周”的同学',
       '显示本文章的作者的姓名:何云峰(wb98·com)',
       )
com1=Combobox(root,textvariable=var,value=list1,state='readonly')
com1.grid(row=1,column=0,columnspan=4,sticky=W+E)
com1.current(0)
 
def com1selection(event):
    # print('选择后:',com1.get())
    print('选择项序号:',com1.current())
    index=com1.current() # 选择项序号
    if index==0: # 显示所有同学
        stra='select * from student'
    elif index==1: # 只显示a班同学
        stra='select * from student where bj="a"'
    elif index==2: # 姓名含“明”字的同学
        stra='select * from student where xm like "%明%"'
    elif index==3: # 姓名第2个字是“明”的同学
        stra='select * from student where xm like "_明%"'
    elif index==4: # 二字姓名,第2个字是“明”的同学
        stra='select * from student where xm like "_明"'
    elif index==5: # 3门功课有一门为100分的同学
        stra='select * from student where yw="100" or sx="100" or yy="100"'
    elif index==6: # 3门功课都不及格的同学
        stra='select * from student where yw<"60" and sx<"60" or yy<"60"'
    elif index==7: # 学号为1,5,7,8的同学
        stra='select * from student where xh in (1,5,7,8)'
    elif index==8: # 三门功课平均分>=90分的同学
        stra='select * from student where (yw+sx+yy)/3>=90'
    elif index==9: # a班按语文成绩排序(降序),辅之以数学降序,英文升序排列
        stra='select * from student  where bj="a" order by yw desc,sx desc,yy asc'
    elif index==10: # 名字不包含“雨”字的同学
        stra='select * from student where xm not like "%雨%"'
    elif index==11: # 语文分数在90到100之间的同学
        stra='select * from student where yw between 90 and 100'
    elif index==12: # 语文分数在60到90分范围以外的高分和低分同学,降序排列
        stra='select * from student where yw not between 60 and 90 order by yw'
    elif index==13: # 姓名第2字和第3字相同的姓名
        stra='select * from student where substr(xm,2,1)=substr(xm,3,1)'
    elif index==14: # 显示姓“郑,何,周”的同学
        stra=stra='select *  from student where substr(xm,1,1) in ("郑","何","周")'
    elif index==15: # 显示本文章的作者的姓名:何云峰(wb98·com)
        stra=stra='select *  from student where xm="何云峰"'
 
    selectjob(stra)
 
com1.bind("<<ComboboxSelected>>",com1selection)
 
root.mainloop()

运行结果


sqlite3数据表的记录在treeview组件的显示及sql语句知识,我就演示到这里。

包括这篇文章在内,我也写的文章都是我学习tkinter编程知识的笔记,以后更多的是写一些实际的小程序代码,加深对知识的了解,巩固学过的知识,你想跟我一起学习tkinter,ttk编程吗?请关注我。收藏我的文章,谢谢。我的网站 wb98.com

 


来源:济亨网

本文链接:http://wb98.com/post/343.html

    << 上一篇 下一篇 >>

    湘公网安备 43011102000514号 - 湘ICP备08100508号