五笔打字通主页
这篇文章我来讲一下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()
运行结果
上面的数据库稍简单一点,不好演示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的结果
我就用这个数据表的数据来演示,用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://www.wb86.com/post/343.html