什么是 SQLite?

SQLite是一个进程内的库,实现了自给自足的、无服务器的、零配置的、事务性的 SQL 数据库引擎。它是一个零配置的数据库,这意味着与其他数据库不一样,您不需要在系统中配置。

就像其他数据库,SQLite 引擎不是一个独立的进程,可以按应用程序需求进行静态或动态连接。SQLite 直接访问其存储文件。

为什么要用 SQLite?

  • 不需要一个单独的服务器进程或操作的系统(无服务器的)。
  • SQLite 不需要配置,这意味着不需要安装或管理。
  • 一个完整的 SQLite 数据库是存储在一个单一的跨平台的磁盘文件。
  • SQLite 是非常小的,是轻量级的,完全配置时小于 400KiB,省略可选功能配置时小于250KiB。
  • SQLite 是自给自足的,这意味着不需要任何外部的依赖。
  • SQLite 事务是完全兼容 ACID 的,允许从多个进程或线程安全访问。
  • SQLite 支持 SQL92(SQL2)标准的大多数查询语言的功能。
  • SQLite 使用 ANSI-C 编写的,并提供了简单和易于使用的 API。
  • SQLite 可在 UNIX(Linux, Mac OS-X, Android, iOS)和 Windows(Win32, WinCE, WinRT)中运行。

SQLite 数据类型

SQLite 数据类型是一个用来指定任何对象的数据类型的属性。SQLite 中的每一列,每个变量和表达式都有相关的数据类型。

您可以在创建表的同时使用这些数据类型。SQLite 使用一个更普遍的动态类型系统。在 SQLite 中,值的数据类型与值本身是相关的,而不是与它的容器相关。

SQLite 存储类

每个存储在 SQLite 数据库中的值都具有以下存储类之一:

存储类 描述
NULL 值是一个 NULL 值。
INTEGER 值是一个带符号的整数,根据值的大小存储在 1、2、3、4、6 或 8 字节中。
REAL 值是一个浮点值,存储为 8 字节的 IEEE 浮点数字。
TEXT 值是一个文本字符串,使用数据库编码(UTF-8、UTF-16BE 或 UTF-16LE)存储。
BLOB 值是一个 blob 数据,完全根据它的输入存储。

SQLite 的存储类稍微比数据类型更普遍。INTEGER 存储类,例如,包含 6 种不同的不同长度的整数数据类型。

SQLite 亲和(Affinity)类型

SQLite支持列的亲和类型概念。任何列仍然可以存储任何类型的数据,当数据插入时,该字段的数据将会优先采用亲缘类型作为该值的存储方式。SQLite目前的版本支持以下五种亲缘类型:

亲和类型 描述
TEXT 数值型数据在被插入之前,需要先被转换为文本格式,之后再插入到目标字段中。
NUMERIC 当文本数据被插入到亲缘性为NUMERIC的字段中时,如果转换操作不会导致数据信息丢失以及完全可逆,那么SQLite就会将该文本数据转换为INTEGER或REAL类型的数据,如果转换失败,SQLite仍会以TEXT方式存储该数据。对于NULL或BLOB类型的新数据,SQLite将不做任何转换,直接以NULL或BLOB的方式存储该数据。需要额外说明的是,对于浮点格式的常量文本,如”30000.0”,如果该值可以转换为INTEGER同时又不会丢失数值信息,那么SQLite就会将其转换为INTEGER的存储方式。
INTEGER 对于亲缘类型为INTEGER的字段,其规则等同于NUMERIC,唯一差别是在执行CAST表达式时。
REAL 其规则基本等同于NUMERIC,唯一的差别是不会将”30000.0”这样的文本数据转换为INTEGER存储方式。
NONE 不做任何的转换,直接以该数据所属的数据类型进行存储。

SQLite 亲和类型(Affinity)及类型名称

下表列出了当创建 SQLite3 表时可使用的各种数据类型名称,同时也显示了相应的亲和类型:

数据类型 亲和类型
INTINTEGERTINYINTSMALLINTMEDIUMINTBIGINTUNSIGNED BIG INTINT2INT8 INTEGER
CHARACTER(20)VARCHAR(255)VARYING CHARACTER(255)NCHAR(55)NATIVE CHARACTER(70)NVARCHAR(100)TEXTCLOB TEXT
BLOB未指定类型 BLOB
REALDOUBLEDOUBLE PRECISIONFLOAT REAL
NUMERICDECIMAL(10,5)BOOLEANDATEDATETIME NUMERIC

Boolean 数据类型

SQLite 没有单独的 Boolean 存储类。相反,布尔值被存储为整数 0(false)和 1(true)。

Date 与 Time 数据类型

SQLite 没有一个单独的用于存储日期和/或时间的存储类,但 SQLite 能够把日期和时间存储为 TEXT、REAL 或 INTEGER 值。

存储类 日期格式
TEXT 格式为 “YYYY-MM-DD HH:MM:SS.SSS” 的日期。
REAL 从公元前 4714 年 11 月 24 日格林尼治时间的正午开始算起的天数。
INTEGER 从 1970-01-01 00:00:00 UTC 算起的秒数。

您可以以任何上述格式来存储日期和时间,并且可以使用内置的日期和时间函数来自由转换不同格式。

SQLite - Python

Python sqlite3 模块 API

序号 API & 描述
1 sqlite3.connect(database [,timeout ,other optional arguments]) 该 API 打开一个到 SQLite 数据库文件 database 的链接。您可以使用 “:memory:” 来在 RAM 中打开一个到 database 的数据库连接,而不是在磁盘上打开。如果数据库成功打开,则返回一个连接对象。当一个数据库被多个连接访问,且其中一个修改了数据库,此时 SQLite 数据库被锁定,直到事务提交。timeout 参数表示连接等待锁定的持续时间,直到发生异常断开连接。timeout 参数默认是 5.0(5 秒)。如果给定的数据库名称 filename 不存在,则该调用将创建一个数据库。如果您不想在当前目录中创建数据库,那么您可以指定带有路径的文件名,这样您就能在任意地方创建数据库。
2 connection.cursor([cursorClass]) 该例程创建一个 cursor,将在 Python 数据库编程中用到。该方法接受一个单一的可选的参数 cursorClass。如果提供了该参数,则它必须是一个扩展自 sqlite3.Cursor 的自定义的 cursor 类。
3 cursor.execute(sql [, optional parameters]) 该例程执行一个 SQL 语句。该 SQL 语句可以被参数化(即使用占位符代替 SQL 文本)。sqlite3 模块支持两种类型的占位符:问号和命名占位符(命名样式)。例如:cursor.execute(“insert into people values (?, ?)”, (who, age))
4 connection.execute(sql [, optional parameters]) 该例程是上面执行的由光标(cursor)对象提供的方法的快捷方式,它通过调用光标(cursor)方法创建了一个中间的光标对象,然后通过给定的参数调用光标的 execute 方法。
5 cursor.executemany(sql, seq_of_parameters) 该例程对 seq_of_parameters 中的所有参数或映射执行一个 SQL 命令。
6 connection.executemany(sql[, parameters]) 该例程是一个由调用光标(cursor)方法创建的中间的光标对象的快捷方式,然后通过给定的参数调用光标的 executemany 方法。
7 cursor.executescript(sql_script) 该例程一旦接收到脚本,会执行多个 SQL 语句。它首先执行 COMMIT 语句,然后执行作为参数传入的 SQL 脚本。所有的 SQL 语句应该用分号 ; 分隔。
8 connection.executescript(sql_script) 该例程是一个由调用光标(cursor)方法创建的中间的光标对象的快捷方式,然后通过给定的参数调用光标的 executescript 方法。
9 connection.total_changes() 该例程返回自数据库连接打开以来被修改、插入或删除的数据库总行数。
10 connection.commit() 该方法提交当前的事务。如果您未调用该方法,那么自您上一次调用 commit() 以来所做的任何动作对其他数据库连接来说是不可见的。
11 connection.rollback() 该方法回滚自上一次调用 commit() 以来对数据库所做的更改。
12 connection.close() 该方法关闭数据库连接。请注意,这不会自动调用 commit()。如果您之前未调用 commit() 方法,就直接关闭数据库连接,您所做的所有更改将全部丢失!
13 cursor.fetchone() 该方法获取查询结果集中的下一行,返回一个单一的序列,当没有更多可用的数据时,则返回 None。
14 cursor.fetchmany([size=cursor.arraysize]) 该方法获取查询结果集中的下一行组,返回一个列表。当没有更多的可用的行时,则返回一个空的列表。该方法尝试获取由 size 参数指定的尽可能多的行。
15 cursor.fetchall() 该例程获取查询结果集中所有(剩余)的行,返回一个列表。当没有可用的行时,则返回一个空的列表。

连接数据库

下面的 Python 代码显示了如何连接到一个现有的数据库。如果数据库不存在,那么它就会被创建,最后将返回一个数据库对象。

1
2
3
4
5
6
7
8
9
10
11
12
13
# -*- coding: utf-8 -*-
"""
@Time : 2023/1/2 13:18
@Author : daokunn
@File :连接数据库.py
@IDE :PyCharm
@Motto: Don’t cry over spilt milk.
"""
import sqlite3

conn = sqlite3.connect('test.db')

print ("数据库打开成功")

创建表

下面的 Python 代码段将用于在先前创建的数据库中创建一个表。

在创建的时候,简易都使用英文,作者这里使用”姓名”这些不推荐,后期出现了一些问题。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import sqlite3

# 连接数据库
conn = sqlite3.connect('test.db')
print ("数据库打开成功")

# 创建一个 cursor游标
c = conn.cursor()

# execute执行一个 SQL 语句。
c.execute('''CREATE TABLE '公司'
(ID INT PRIMARY KEY NOT NULL,
'姓名' TEXT NOT NULL,
'年龄' INT NOT NULL,
'地址' CHAR(50),
'工资' REAL);''')
print ("数据表创建成功")
conn.commit()
conn.close()

INSERT 操作

下面的 Python 程序显示了如何在上面创建的 COMPANY 表中创建记录:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import sqlite3

conn = sqlite3.connect('test.db')
c = conn.cursor()
print ("数据库打开成功")

c.execute("INSERT INTO '公司' (ID,'姓名','年龄','地址','工资') \
VALUES (1, '阿福', 20, '江西赣州', 20000.00 )")

c.execute("INSERT INTO '公司' (ID,'姓名','年龄','地址','工资') \
VALUES (2, '小璇', 18, '江西抚州', 15000.00 )")

c.execute("INSERT INTO '公司' (ID,'姓名','年龄','地址','工资') \
VALUES (3, '道坤', 21, '江西九江', 20000.00 )")

c.execute("INSERT INTO '公司' (ID,'姓名','年龄','地址','工资') \
VALUES (4, '小彭', 21, '江西萍乡 ', 65000.00 )")

conn.commit()
print ("数据插入成功")
conn.close()

SELECT 操作

下面的 Python 程序显示了如何从前面创建的 COMPANY 表中获取并显示记录:

查询小璇

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import sqlite3

conn = sqlite3.connect('test.db')
c = conn.cursor()
print ("数据库打开成功")

# 查询序号为2,小璇的信息
cursor = c.execute("SELECT * FROM '公司' WHERE id =?",(2,))
for row in cursor:
print(f'ID={row[0]}')
# print(row[5])
print(f'姓名={row[1]}')
print(f'年龄={row[2]}')
print(f'地址={row[3]}')
print(f'工资={row[4]}')
print()


print ("数据操作成功")
conn.close()

image-20230102135250571

查询所有人

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import sqlite3

conn = sqlite3.connect('test.db')
c = conn.cursor()
print ("数据库打开成功")

# cursor = c.execute("SELECT ID,'姓名','年龄','地址','工资' from '公司' ")
# 这句注释因为答案不准确
# 用 * 可以查询
cursor = c.execute("SELECT * from '公司' ")
for row in cursor:
print(f'ID={row[0]}')
print(f'姓名={row[1]}')
print(f'年龄={row[2]}')
print(f'地址={row[3]}')
print(f'工资={row[4]}')
print()


print ("数据操作成功")
conn.close()

UPDATE 操作

下面的 Python 代码显示了如何使用 UPDATE 语句来更新任何记录,然后从 COMPANY 表中获取并显示更新的记录:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import sqlite3

conn = sqlite3.connect('test.db')
c = conn.cursor()
print ("数据库打开成功")

c.execute("UPDATE '公司' set '工资' = 30000000.00 where ID=1")
conn.commit()
print('改变次数',conn.total_changes)

cursor = conn.execute("SELECT * from '公司'")
for row in cursor:
print(f'ID={row[0]}')
print(f'姓名={row[1]}')
print(f'年龄={row[2]}')
print(f'地址={row[3]}')
print(f'工资={row[4]}')
print()


print ("数据操作成功")
conn.close()

image-20230102140419879

DELETE 操作

下面的 Python 代码显示了如何使用 DELETE 语句删除任何记录,然后从 COMPANY 表中获取并显示剩余的记录:

删除 ID=1 的数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import sqlite3

conn = sqlite3.connect('test.db')
c = conn.cursor()
print ("数据库打开成功")

c.execute("DELETE from '公司' where ID=1;")
# 提交,修改生效
conn.commit()
cursor = conn.execute("SELECT * from '公司' ")
for row in cursor:
print(f'ID={row[0]}')
print(f'姓名={row[1]}')
print(f'年龄={row[2]}')
print(f'地址={row[3]}')
print(f'工资={row[4]}')
print()

print ("数据操作成功")
conn.close()

ID = 1 被删除了

image-20230102140832159

sqlite 基本不区分大小写(除去个别),然后不建议使用中文!不建议使用中文!

最后,特别感谢SQLite – Python | 菜鸟教程 (runoob.com),文章是从菜鸟教程学习记录的,更加详细的信息可以去菜鸟教程学习!