Python sqlite3 极简教程
本文主要介绍如何使用Python的sqlite3标准库操作SQLite数据库文件帮助大家快速上手0. 简介SQLite是一种用C语言编写的非常轻量的数据库所有内容都集成在一个.db文件中一个.db文件就是一个数据库Python标准库里的sqlite3可以很方便的结合SQL语句操作SQLite数据库文件由于属于Python标准库所以我们不需要额外的安装命令直接import sqlite3即可在数据库操作中我们的行为常被叫做CRUD或者说增删改查(其实叫 增查改删 才和字母能对应上)所以接下来我也会分成这4个部分来介绍CCreateRReadUUpdateDDeletePython 操作 SQLite 数据库基本流程1. Create 新增数据1.1 创建数据库(database)、数据表(table)importsqlite3# 创建与数据库文件的连接(connection)一个连接对象# 如果这个数据库不存在那么会自动创建一个新的数据库connectionsqlite3.connect(test.db)# 数据库文件名为test.db# 创建一个cursor用来操作数据一个游标对象cursorconnection.cursor()# 编写创建新数据表的SQL语句sql_create_table CREATE TABLE user(id INTEGER PRIMARY KEY, name TEXT); cursor.execute(sql_create_table)# 执行SQL语句cursor.close()# 关闭游标connection.close()# 关闭连接执行完以后你会发现运行代码的同级目录下会多一个test.db文件如果再次运行会报错不是因为test.db文件已存在而是因为这个数据库里已经有一个叫user的数据表了不能再创建一个一样的表了每个connection和cursor用完都要记得关闭养成好习惯理论上每个SQLite数据库的.db文件可以创建多个connection多个cursor大家可以自行向AI咨询相关知识本文只介绍一个connection一个cursor的简单使用方法建议要执行的SQL语句可以创建一个单独的变量保存变量名推荐sql_功能简介使用三单引号包裹内容 (三双引号表示函数docstring所以不用它)三引号可以跨行编写字符串并且不需要对字符串中的其它引号进行转义因为SQL语句往往很多行并且语法和Python代码类似但又不同如果直接把SQL字符串写在execute的括号里可读性差注意每条SQL语句后要加英文分号;SQL语句实际上是不区分大小写的但是为了可读性和代码维护方便推荐把关键字用全大写其它用全小写SQLite数据类型遇到不太理解的大家可以自行咨询AI我尽量简洁一点1.2 插入(新增)数据到数据表中插入(新增)数据的SQL语法格式为INSERT INTO 表名(字段名1, 字段名2, ..., 字段名n) VALUES(字段值1, 字段值2, ..., 字段值n)示例代码importsqlite3# 创建与数据库文件的链接(connection)一个连接对象# 如果这个数据库不存在那么会自动创建一个新的数据库connectionsqlite3.connect(test.db)# 数据库文件名为test.db# 创建一个cursor用来操作数据一个游标对象cursorconnection.cursor()# 编写 插入新数据 到 数据表 的SQL语句sql_insert INSERT INTO user(id, name) VALUES(1, xiao); INSERT INTO user(id, name) VALUES(2, tian); INSERT INTO user(id, name) VALUES(3, 小天); cursor.executescript(sql_insert)# 执行SQL语句connection.commit()cursor.close()connection.close()当我们的SQL语句有多行时需要使用cursor.executescript()方法cursor.execute()只能执行一行SQL语句在SQL语句中字符串字面量用单引号包裹当我们修改数据(增、改、删)之后可以使用connection.commit()提交操作如果操作失败数据库会自动回退到修改之前下面这种写法其实是不安全且比较啰嗦的写法sql_insert INSERT INTO user(id, name) VALUES(1, xiao); INSERT INTO user(id, name) VALUES(2, tian); INSERT INTO user(id, name) VALUES(3, 小天); cursor.executescript(sql_insert) # 执行SQL语句用Python操作数据库时应该用?占位防止SQL注入(大家自行AI一下)更推荐的写法是sql_insert INSERT INTO user(id,name) VALUES(?, ?); data[(1,xiao),(2,tian),(3,小天)]cursor.executemany(sql_insert,data)批量插入数据时优先使用cursor.executemany它只接收一行SQL语句然后使用数据列表中的每个元组作为参数值重复执行多次该SQL语句由于需要频繁修改代码测试大家报错了可以直接把数据库文件删了用代码重新创建数据库、表并插入数据总结代码importsqlite3# 创建与数据库文件的链接(connection)一个连接对象# 如果这个数据库不存在那么会自动创建一个新的数据库connectionsqlite3.connect(test.db)# 数据库文件名为test.db# 创建一个cursor用来操作数据一个游标对象cursorconnection.cursor()# 编写 创建新数据表 的SQL语句sql_create_table CREATE TABLE user(id INTEGER PRIMARY KEY, name TEXT); cursor.execute(sql_create_table)# 执行SQL语句# 编写 插入新数据 到 数据表 的SQL语句sql_insert INSERT INTO user(id, name) VALUES(?, ?); data[(1,xiao),(2,tian),(3,小天)]cursor.executemany(sql_insert,data)# 执行SQL语句connection.commit()# 提交cursor.close()connection.close()2. Read 读取数据在SQL语句中查看数据用的是SELECT这个关键词select 这个英文单词的意思“挑选、筛选”因为数据库读取数据不是直接读取全部数据而是按条件挑选数据查看数据的SQL语法格式SELECT 字段名1, 字段名2, ..., 字段名n FROM 表名 WHERE 查询条件示例代码importsqlite3# 创建与数据库文件的连接(connection)一个连接对象# 如果这个数据库不存在那么会自动创建一个新的数据库connectionsqlite3.connect(test.db)# 数据库文件名为test.db# 创建一个cursor用来操作数据一个游标对象cursorconnection.cursor()# 编写 查看数据 的SQL语句sql_select SELECT * FROM user; cursor.execute(sql_select)# 执行查询SQL服务端暂存匹配结果数据未载入Python内存resultcursor.fetchall()# 将数据加载到Python程序当中print(result)cursor.close()connection.close()可以把test.db数据库文件删了我们和之前的代码融合一下重头来一遍importsqlite3# 创建与数据库文件的连接(connection)一个连接对象# 如果这个数据库不存在那么会自动创建一个新的数据库connectionsqlite3.connect(test.db)# 数据库文件名为test.db# 创建一个cursor用来操作数据一个游标对象cursorconnection.cursor()# 编写 创建新数据表 的SQL语句sql_create_table CREATE TABLE user(id INTEGER PRIMARY KEY, name TEXT); cursor.execute(sql_create_table)# 执行SQL语句# 编写 插入新数据 到 数据表 的SQL语句sql_insert INSERT INTO user(id, name) VALUES(?, ?); data[(1,xiao),(2,tian),(3,小天)]cursor.executemany(sql_insert,data)# 执行SQL语句connection.commit()# 提交# 编写 查看数据 的SQL语句sql_select SELECT * FROM user; cursor.execute(sql_select)# 执行查询SQL服务端暂存匹配结果数据未载入Python内存resultcursor.fetchall()# 将数据加载到Python程序当中print(result)cursor.close()connection.close()其实代码是有一点长的当逻辑较复杂代码较多时会容易忘记commit或者忘记closecursor 和 connection这个时候 Python 的with语句就起到一个十分方便的作用了sqlite3库中的connection对象是支持with语法的在with语句结束后会自动commit、close对应的connection但是cursor类型的对象暂不支持with语法(删掉 test.db 后重新运行) 示例代码importsqlite3# 创建与数据库文件的连接(connection)一个连接对象# 如果这个数据库不存在那么会自动创建一个新的数据库withsqlite3.connect(test.db)asconnection:# 数据库文件名为test.db# 创建一个cursor用来操作数据一个游标对象cursorconnection.cursor()# 编写 创建新数据表 的SQL语句sql_create_table CREATE TABLE user(id INTEGER PRIMARY KEY, name TEXT); cursor.execute(sql_create_table)# 执行SQL语句# 编写 插入新数据 到 数据表 的SQL语句sql_insert INSERT INTO user(id, name) VALUES(?, ?); data[(1,xiao),(2,tian),(3,小天)]cursor.executemany(sql_insert,data)# 执行SQL语句# 编写 查看数据 的SQL语句sql_select SELECT * FROM user; cursor.execute(sql_select)# 执行查询SQL服务端暂存匹配结果数据未载入Python内存resultcursor.fetchall()# 将数据加载到Python程序当中print(result)cursor.close()省略了connection的commit和close两个部分但是代码还是很长其实我们可以把cursor的部分也省略掉我们现在是手动创建 cursor 并手动关闭并且通过我们创建的 cursor 来执行SQL语句但是实际上connection对象也可以直接执行SQL语句它内部会创建一个临时cursor并在语句执行结束后返回该cursor如果没有通过变量保存返回的cursor相当于这个cursor用完后被丢弃(删掉 test.db 后重新运行) 示例代码importsqlite3# 创建与数据库文件的连接(connection)一个连接对象# 如果这个数据库不存在那么会自动创建一个新的数据库withsqlite3.connect(test.db)asconnection:# 数据库文件名为test.db# 编写 创建新数据表 的SQL语句sql_create_table CREATE TABLE user(id INTEGER PRIMARY KEY, name TEXT); connection.execute(sql_create_table)# 执行SQL语句# 编写 插入新数据 到 数据表 的SQL语句sql_insert INSERT INTO user(id, name) VALUES(?, ?); data[(1,xiao),(2,tian),(3,小天)]connection.executemany(sql_insert,data)# 执行SQL语句# 编写 查看数据 的SQL语句sql_select SELECT * FROM user; # 执行查询SQL服务端暂存匹配结果数据未载入Python内存cursorconnection.execute(sql_select)# 保存返回的cursorresultcursor.fetchall()# 将数据加载到Python程序当中print(result)connection执行SQL语句的方法名和cursor的一样execute、executemany、executescript注意读取数据时必须通过cursor类型的对象才能fetch所以需要保存connection执行查询操作后返回的cursor读取数据部分的代码也可以通过方法链简写为# 编写 查看数据 的SQL语句sql_select SELECT * FROM user; # 执行查询SQL并将数据加载到Python程序当中resultconnection.execute(sql_select).fetchall()print(result)cursor类型对象获取已选择的数据除了fetchall还有fetchonefetchmany方法返回值读取逻辑适用场景优缺点fetchone()单行元组 / None读取游标下一行无数据返回 None大数据逐行遍历、流式读取内存占用极小需要循环处理fetchmany(size)多行元组列表读取后续 size 行默认size1无数据返回空列表分页查询、分批处理大量数据可控内存负载可自定义批次数量fetchall()全部结果元组列表一次性读取游标剩余所有行无数据返回空列表数据量小需要一次性拿到全部结果代码最简数据量大时内存占用高确保数据库、数据表、数据都已存在运行示例代码importsqlite3# 创建与数据库文件的连接(connection)一个连接对象# 如果这个数据库不存在那么会自动创建一个新的数据库withsqlite3.connect(test.db)asconnection:# 数据库文件名为test.db# 编写 查看数据 的SQL语句sql_select SELECT * FROM user; # 执行查询SQL并将数据加载到Python程序当中resultconnection.execute(sql_select).fetchall()print(result)# 打印结果[(1, xiao), (2, tian), (3, 小天)]# 上一个cursor已被丢弃需要重新创建cursorconnection.execute(sql_select)print(cursor.fetchone())# 打印结果(1, xiao)print(cursor.fetchone())# 打印结果(2, tian)# 上一个cursor位置已经移动到第3条数据前面想要重新读取需要移动cursor或重新创建cursorconnection.execute(sql_select)print(cursor.fetchmany(2))# 打印结果[(1, xiao), (2, tian)]3. Update 更新(修改)数据SQL语法格式UPDATE 表名 SET 字段名 字段值 WHERE 查询条件示例代码1importsqlite3# 创建与数据库文件的连接(connection)一个连接对象# 如果这个数据库不存在那么会自动创建一个新的数据库withsqlite3.connect(test.db)asconnection:# 数据库文件名为test.db# 编写 更新数据 的SQL语句sql_update UPDATE user SET name ? WHERE id ?; connection.execute(sql_update,(XIAOTIAN,3))sql_select SELECT * FROM user; resultconnection.execute(sql_select).fetchall()print(result)示例代码2importsqlite3# 创建与数据库文件的连接(connection)一个连接对象# 如果这个数据库不存在那么会自动创建一个新的数据库withsqlite3.connect(test.db)asconnection:# 数据库文件名为test.db# 编写 更新数据 的SQL语句sql_update UPDATE user SET name ? WHERE id ?; params[(xiao,1),(tian,2),(XIAOTIAN,3)]connection.executemany(sql_update,params)sql_select SELECT * FROM user; resultconnection.execute(sql_select).fetchall()print(result)4. Delete 删除数据SQL语法格式DELETE FROM 表名 WHERE 查询条件示例代码importsqlite3# 创建与数据库文件的连接(connection)一个连接对象# 如果这个数据库不存在那么会自动创建一个新的数据库withsqlite3.connect(test.db)asconnection:# 数据库文件名为test.db# 编写 删除数据 的SQL语句sql_delete DELETE FROM user WHERE id ?; connection.execute(sql_delete,(3,))sql_select SELECT * FROM user; resultconnection.execute(sql_select).fetchall()print(result)# 打印结果[(1, xiao), (2, tian)]注意即使只有一个参数也要保证传入的是元组类型