🐸 青蛙编程网
首页 / Python / Flask / 5. 数据库入门

数据库入门

这是什么:数据库 = 让数据长期住下来、还能随时查出来的仓库;本章用 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 不写等于白干。

动手改

  1. 新建 /clear 路由:执行 DELETE FROM messages 清空留言,然后重定向回首页
  2. 把首页查询改成只显示最新 5 条(提示:SQL 末尾加 LIMIT 5)
  3. 单独写一段脚本(不用开网站),直接往库里插入 3 条留言,再打开网站看它们在不在

下一章:综合练习,把四章所学拧成一个真正的项目 🐸

📥 下载本章代码

ZIP 内含本章全部代码文件与说明,解压即用,与教程内容同步生成。