数据库入门
这是什么:数据库 = 让数据长期住下来、还能随时查出来的仓库;本章用 SQLite,零安装、Python 自带 sqlite3。
为什么用:上一章的留言板有个致命伤:留言存在 Python 的列表里,程序一重启就全部蒸发。没有数据库,数据存不住,也查不快。
如何用:本章用 sqlite3 走一遍「建表 → 插入 → 查询」,让数据真正「住下来」。
为什么需要数据库
存数据,你可能想:写进文本文件不就行了?数据量小可以,一多就露馅:
- 想「查最新的 10 条留言」,得自己把整个文件翻一遍
- 两个用户同时写入,内容可能互相覆盖
- 格式全靠自己约定,一乱就全乱
数据库就是专业的数据仓库:存取规范、查询飞快、还管并发。我们用 SQLite——世界上使用最广的数据库,小到整个库就是一个文件,而且 Python 内置了 sqlite3 模块,零安装、开箱即用(大型项目常用 MySQL、PostgreSQL,但入门 SQLite 完全够)。
五分钟上手 sqlite3
新建 test_db.py,体验一遍「建表 → 插入 → 查询」:
import sqlite3
conn = sqlite3.connect("board.db") # 没有这个文件就自动创建
cur = conn.cursor()
cur.execute("""
CREATE TABLE IF NOT EXISTS messages (
id INTEGER PRIMARY KEY AUTOINCREMENT,
content TEXT NOT NULL
)
""")
cur.execute("INSERT INTO messages (content) VALUES (?)", ("青蛙的第一条留言",))
conn.commit() # 别忘了提交,否则写入不生效
cur.execute("SELECT * FROM messages")
print(cur.fetchall())
conn.close()
运行 python test_db.py,输出:
[(1, '青蛙的第一条留言')]
再运行一次,列表里就有两条了——数据住进了文件,程序重启也不怕。
| 代码 | 作用 |
|---|---|
sqlite3.connect("board.db") |
连接数据库文件,没有就自动创建 |
CREATE TABLE IF NOT EXISTS |
建表:规定有哪些列、什么类型;IF NOT EXISTS 保证重复执行也不报错 |
id INTEGER PRIMARY KEY AUTOINCREMENT |
自增编号,每插一条自动 +1,是每条数据的「身份证」 |
VALUES (?) + 后面的元组 |
问号占位符:数据由参数安全传入,绝不直接拼进 SQL 字符串——防注入攻击的铁规矩 |
conn.commit() |
确认写入(不 commit,插入等于白干) |
cur.fetchall() |
取出查询到的所有行,每行是一个元组 |
把留言板搬进数据库
改造上一章的项目,app.py 换成:
import sqlite3
from flask import Flask, render_template, request, redirect
app = Flask(__name__)
def db():
conn = sqlite3.connect("board.db")
conn.row_factory = sqlite3.Row # 每行能用列名取值,像字典
conn.execute("""
CREATE TABLE IF NOT EXISTS messages (
id INTEGER PRIMARY KEY AUTOINCREMENT,
content TEXT NOT NULL
)
""")
return conn
@app.route("/")
def home():
conn = db()
messages = conn.execute("SELECT * FROM messages ORDER BY id DESC").fetchall()
conn.close()
return render_template("board.html", messages=messages)
@app.route("/add", methods=["POST"])
def add():
text = request.form.get("message", "").strip()
if text:
conn = db()
conn.execute("INSERT INTO messages (content) VALUES (?)", (text,))
conn.commit()
conn.close()
return redirect("/")
if __name__ == "__main__":
app.run(debug=True)
templates/board.html 只改一行——留言从字符串变成了数据库的行,要用列名取值:
<h1>留言板</h1>
{% for m in messages %}
<p>{{ m['content'] }}</p>
{% endfor %}
<form method="post" action="/add">
<input name="message" placeholder="写下你的留言">
<button type="submit">提交</button>
</form>
运行起来发几条留言,然后 Ctrl + C 停掉,再 python app.py 重启——留言还在! 这就是数据库的底气。
记忆口诀
connect 连库执行 SQL,问号占位保平安,commit 不写等于白干。
动手改
- 新建
/clear路由:执行DELETE FROM messages清空留言,然后重定向回首页 - 把首页查询改成只显示最新 5 条(提示:SQL 末尾加
LIMIT 5) - 单独写一段脚本(不用开网站),直接往库里插入 3 条留言,再打开网站看它们在不在
下一章:综合练习,把四章所学拧成一个真正的项目 🐸