https://github.com/xavierjiezou/python-sqlite3-tutorial
Tutorial for splite3 module based on Python.
https://github.com/xavierjiezou/python-sqlite3-tutorial
python sqlite
Last synced: about 2 months ago
JSON representation
Tutorial for splite3 module based on Python.
- Host: GitHub
- URL: https://github.com/xavierjiezou/python-sqlite3-tutorial
- Owner: XavierJiezou
- Created: 2022-04-21T04:28:32.000Z (about 4 years ago)
- Default Branch: main
- Last Pushed: 2022-04-21T04:33:15.000Z (about 4 years ago)
- Last Synced: 2025-03-25T11:01:59.702Z (over 1 year ago)
- Topics: python, sqlite
- Language: HTML
- Homepage: https://XavierJiezou.github.io/Python-Sqlite3-Tutorial
- Size: 94.7 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.ipynb
Awesome Lists containing this project
README
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Python-Sqlite3-Tutorial"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 引言"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"SQLite 是一个由 C 语言编写的库,它提供了一个轻量级的基于磁盘的数据库,不需要单独开一个数据库服务器,并允许使用 SQL 语句访问数据库。\n",
"\n",
"判断是否使用 SQLite 的标准:\n",
"\n",
"- 数据与应用分离:不适用 SQLite\n",
"- 要求高并发性:不适用 SQLite\n",
"- 大数据:不适用 SQLite\n",
"- 否则,选择 SQLite\n",
"\n",
"SQLite 不是一个 client/server 架构的数据库引擎(如 MySQL、Oracle、PostgreSQL 或 SQL Server 等),它致力于为单个应用程序提供本地存储,强调经济性、效率、可靠性、独立性和简单性,而不追求可伸缩性、并发性、集中性和控制性。\n",
"\n",
"Python3 内置了一个名为 `sqlite3` 标准模块,提供了 SQLite 数据库操作的一整套接口,本文是利用该模块实现数据库操作的零基础入门教程。\n",
"\n",
"> sqlite3 是以 [pysqlite](http://github.com/ghaering/pysqlite) 的名称在外部进行开发,其开发参考了 [PEP 249](https://www.python.org/dev/peps/pep-0249) 定义的 `Database API Specification 2.0`(数据库接口规范 2.0),以及 [SQLite](https://www.sqlite.org/) 官网提供的 SQL 语法和数据类型。"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 安装"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"`sqlite3` 是 Python3 的内置标准模块,不用额外安装。"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 教程"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"这里简要介绍一下数据库操作的一般流程:\n",
"\n",
"1. 开启数据库连接\n",
"2. 新建游标\n",
"3. 调用游标执行 SQL 语句\n",
"4. 关闭游标\n",
"5. 提交数据库更改(如果抛出异常,则回滚)\n",
"6. 关闭数据库连接\n",
"\n",
"最常见的增删改查操作都通过执行 SQL 语句中实现。"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 创建和关闭数据库连接"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"如要使用该模块,首先必须创建一个表示数据库的 `Connection` 对象。"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"import sqlite3\n",
"conn = sqlite3.connect('demo.db')\n",
"conn.close()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"如果不存在 `demo.db` 文件,将自动创建;如果存在,则直接进行连接。"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 新建表"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"一旦你有了一个 `Connection`,你可以创建一个 `Cursor` 对象,并调用它的 `execute()` 方法来执行 SQL 命令,比如在数据库中新建一个名为 `student` 的表。"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"import sqlite3\n",
"conn = sqlite3.connect('demo.db')\n",
"cursor = conn.cursor()\n",
"cursor.execute('''\n",
" create table student(\n",
" id integer primary key autoincrement not null,\n",
" name text,\n",
" age integer\n",
" )\n",
"''')\n",
"conn.commit()\n",
"cursor.close()\n",
"conn.close()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"如果表已经存在,会抛出 `OperationalError` 异常。为避免抛出该异常,可以使用 Python 的异常捕捉进行处理,也可以在 SQL 语句中进行表是否存在的判断。"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"import sqlite3\n",
"conn = sqlite3.connect('demo.db')\n",
"cursor = conn.cursor()\n",
"cursor.execute('''\n",
" create table if not exists student(\n",
" id integer primary key autoincrement not null,\n",
" name text,\n",
" age integer\n",
" )\n",
"''')\n",
"conn.commit()\n",
"cursor.close()\n",
"conn.close()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 插入记录【增】"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"接下来,让我们向表中插入几条记录用于测试。"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- 插入一条记录"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"import sqlite3\n",
"conn = sqlite3.connect('demo.db')\n",
"cursor = conn.cursor()\n",
"data = (1, 'john', 18)\n",
"sql = 'insert into student values (?, ?, ?)'\n",
"cursor.execute(sql, data)\n",
"conn.commit()\n",
"cursor.close()\n",
"conn.close()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- 插入多行记录"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
"import sqlite3\n",
"conn = sqlite3.connect('demo.db')\n",
"cursor = conn.cursor()\n",
"data = [\n",
" (2, 'lily', 19),\n",
" (3, 'mike', 20)\n",
"]\n",
"sql = 'insert into student values (?, ?, ?)'\n",
"cursor.executemany(sql, data)\n",
"conn.commit()\n",
"cursor.close()\n",
"conn.close()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"通常,你不应该使用 Python 的字符串操作来组合 SQL 语句,因为这样做是不安全的,容易受到 SQL 注入攻击。正确的做法是使用 `?` 作为占位符,然后将值的元组或元组嵌套的列表作为第二个参数传递给 execute() 或executemany() 方法。"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 查询记录【查】"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- 查询表中所有字段的记录"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"(1, 'john', 18)\n",
"(2, 'lily', 19)\n",
"(3, 'mike', 20)\n"
]
}
],
"source": [
"import sqlite3\n",
"conn = sqlite3.connect('demo.db')\n",
"cursor = conn.cursor()\n",
"sql = 'select * from student'\n",
"cursor.execute(sql)\n",
"for item in cursor:\n",
" print(item)\n",
"conn.commit()\n",
"cursor.close()\n",
"conn.close()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- 查询表中指定字段的记录"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"('john',)\n",
"('lily',)\n",
"('mike',)\n"
]
}
],
"source": [
"import sqlite3\n",
"conn = sqlite3.connect('demo.db')\n",
"cursor = conn.cursor()\n",
"sql = 'select name from student'\n",
"cursor.execute(sql)\n",
"for item in cursor:\n",
" print(item)\n",
"conn.commit()\n",
"cursor.close()\n",
"conn.close()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- 根据条件查询表中的记录"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"(1, 'john', 18)\n"
]
}
],
"source": [
"import sqlite3\n",
"conn = sqlite3.connect('demo.db')\n",
"cursor = conn.cursor()\n",
"sql = 'select * from student where age = 18'\n",
"cursor.execute(sql)\n",
"for item in cursor:\n",
" print(item)\n",
"conn.commit()\n",
"cursor.close()\n",
"conn.close()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 修改记录【改】"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"例如,将 `mike` 的 `name` 修改为 `mary`。"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [],
"source": [
"import sqlite3\n",
"conn = sqlite3.connect('demo.db')\n",
"cursor = conn.cursor()\n",
"sql = \"update student set name = 'mary' where name = 'mike'\"\n",
"cursor.execute(sql)\n",
"conn.commit()\n",
"cursor.close()\n",
"conn.close()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 删除记录【删】"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- 按条件删除表记录"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [],
"source": [
"import sqlite3\n",
"conn = sqlite3.connect('demo.db')\n",
"cursor = conn.cursor()\n",
"sql = \"delete from student where name = 'lily'\"\n",
"cursor.execute(sql)\n",
"conn.commit()\n",
"cursor.close()\n",
"conn.close()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- 清空表中所有记录"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [],
"source": [
"import sqlite3\n",
"conn = sqlite3.connect('demo.db')\n",
"cursor = conn.cursor()\n",
"sql = 'delete from student'\n",
"cursor.execute(sql)\n",
"conn.commit()\n",
"cursor.close()\n",
"conn.close()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 删除表"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [],
"source": [
"import sqlite3\n",
"conn = sqlite3.connect('demo.db')\n",
"cursor = conn.cursor()\n",
"sql = 'drop table student'\n",
"cursor.execute(sql)\n",
"conn.commit()\n",
"cursor.close()\n",
"conn.close()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 附录"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"数据库表操作常用的 SQL 命令:\n",
"\n",
"| 功能 | 命令 |\n",
"|--------------------------|------------------------------------------------------------------------------------------------------------------------------|\n",
"| 新建表 | create table [if not exists] `TABLE_NAME` `COLUMN_DEF` |\n",
"| 清空表中所有记录 | delete from `TABLE_NAME` |\n",
"| 按条件清除表记录 | delete from `TABLE_NAME` where `EXPR` |\n",
"| 删除表 | drop table [if exists] `TABLE_NAME` |\n",
"| 查看表字段 | pragma table_info(`TABLE_NAME`) |\n",
"| 修改表名称 | alter table `OLD_TABLE_NAME` rename to `NEW_TABLE_NAME` |\n",
"| 添加表字段 | alter table `TABLE_NAME` add `NEW_COLUMN_NAME` [`COLUMN_DEF`] |\n",
"| 删除表字段 | alter table `TABLE_NAME` drop `COLUMN_NAME` |\n",
"| 修改字段名 | alter table `TABLE_NAME` rename column `OLD_COLUMN_NAME` to `NEW_COLUMN_NAME` |\n",
"| 插入表记录 | insert into `TABLE_NAME` [(`COLUMN_NAME`)] values (`EXPR`) |\n",
"| 向表中插入查询返回的数据 | insert into `TABLE_NAME` select `EXPR` |\n",
"| 在表末尾插入一条默认数据 | insert into `TABLE_NAME` default values |\n",
"| 更新表记录 | update `TABLE_NAME` set `COLUMN1_NAME` = `EXPR1` , `COLUMN2_NAME` = `EXPR2` [from `TABLE_NAME` or `SUBQUERY`] [where `EXPR`] |\n",
"| 查询表中所有字段的记录 | select * from `TABLE_NAME` [where `EXPR`] [group by `EXPR`] [order by `ORDERING-TERM`] [limit `EXPR`] |\n",
"| 查询表中指定字段的记录 | select `COLUMN1_NAME` , `COLUMN2_NAME` from `TABLE_NAME` |\n",
"\n",
"更多关于 SQL 语句的详细信息请参见[官方文档](https://www.sqlite.org/doclist.html)。"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 概念"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 数据类型"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"SQLite 官方定义了如下五种[数据类型](https://www.sqlite.org/datatype3.html):\n",
"\n",
"- NULL:空值。\n",
"- INTEGER:整数。\n",
"- REAL:小数。\n",
"- TEXT:文本字符串。\n",
"- BLOB:二进制对象。\n",
"\n",
"SQLite 没有单独的布尔数据存储类型,布尔值被存储为整数 0 (false) 和 1 (true)。"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"在 sqlite3 模块中,Python 数据类型和 SQLite 数据类型可以相互转换。"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Python 数据类型在 SQLite 中的呈现方式:\n",
"\n",
"| Python type | SQLite type |\n",
"|--------------------|----------------|\n",
"| None | NULL |\n",
"| int | INTEGER |\n",
"| long | INTEGER |\n",
"| float | REAL |\n",
"| str (UTF8-encoded) | TEXT |\n",
"| unicode | TEXT |\n",
"| buffer | BLOB |"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"SQLite 数据类型在 Python 中按照如下方式转换:\n",
"\n",
"| SQLite type | Python type |\n",
"|----------------|-------------------------------------------------------------------|\n",
"| NULL | None |\n",
"| INTEGER | int or long, depending on size |\n",
"| REAL | float |\n",
"| TEXT | depends on text_factory, unicode by default |\n",
"| BLOB | buffer |"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 字段定义"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"除数据类型外,定义字段时还有很多其他可选参数:\n",
"\n",
"- primary key:主键。其值能唯一标识表中的每一行。\n",
"- primary key autoincrement:主键自增。插入数据时无需带上主键的值,因为它可以自动递增赋值。\n",
"- not null:非空。该字段内不允许出现空值。\n",
"- unique:唯一。该字段内不允许出现重复值。\n",
"- default:默认。设置该字段的默认值。"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 接口"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Connection\n",
"\n",
"Connection 对象主要实现了以下方法:\n",
"\n",
"- .close():关闭数据库连接。关闭之后,试图对数据库进行的任何操作都将引发 `Error` 异常。\n",
"- .commit():提交所有挂起的任务到数据库。\n",
"- .rollback():回滚数据库到挂起任务尚未执行之前。值得注意的是,如果在没有提交更改的情况下就关闭了数据库连接,将会自动执行隐式回滚。\n",
"- .cursor():返回一个新的使用该连接的 `Cursor` 对象。"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Cursor\n",
"\n",
"Cursor 对象主要实现了以下属性和方法:\n",
"\n",
"- 属性\n",
" - .description:游标描述信息。如果没有有意义的信息,就返回 `None`。\n",
" - .rowcount:执行最后一个 SQL 语句操作的行数。如果没有 SQL 语句执行,返回 `-1`。\n",
"- 方法\n",
" - .close():关闭游标。关闭之后,试图对游标进行的任何操作都将引发 `Error` 异常。\n",
" - .execute(sql [, parameters]):准备并执行 SQL 语句。\n",
" - .executemany(sql, seq_of_parameters):准备并执行 SQL 语句。接受的参数是一个序列。\n",
" - .fetchone():获取查询结果中的一行,返回单个序列。如果查询结果结果是空,返回 `None`。如果之前执行的 sql 语句没有任何返回结果,抛出 `Error` 异常。\n",
" - .fetchmany([size=cursor.arraysize]):获取多行查询结果,返回一个嵌套的序列,例如,嵌套在列表里面的元组。\n",
" - .fetchall():获取查询结果的所有行,返回一个嵌套的序列。"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 参考\n",
"\n",
"> - [SQLite Home Page](https://www.sqlite.org/index.html)\n",
"> - [PEP 249 – Python Database API Specification v2.0](https://peps.python.org/pep-0249/)\n",
"> - [sqlite3 — DB-API 2.0 interface for SQLite databases](https://pysqlite.readthedocs.io/en/latest/sqlite3.html)"
]
}
],
"metadata": {
"interpreter": {
"hash": "ecf5722fdaf1897a315d257d89d94520bfcaa453217d5becf09b39e73618b0de"
},
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.1"
}
},
"nbformat": 4,
"nbformat_minor": 2
}