Flask学习笔记 - 数据库

Flask 数据库操作

Flask 提供了多种方式来与数据库进行交互,包括直接使用 SQL 和利用 ORM(对象关系映射)工具,如 SQLAlchemy。

  1. 使用SQLAlchemy
  2. 创建和管理数据库:使用 db.create_all() 创建表。
  3. CRUD 操作:添加、读取、更新和删除记录。
  4. 查询操作:执行基本和复杂查询,包括排序和分页。
  5. Flask-Migrate:使用 Flask-Migrate 管理数据库迁移。
  6. 执行原始 SQL:使用原始 SQL 语句进行数据库操作。

使用SQLAlchemy

SQLAlchemy 是一个强大的 ORM 库,可以简化数据库操作,通过 Python 对象与数据库表进行交互。

Flask-SQLAlchemy 是 Flask 的一个扩展,用于集成 SQLAlchemy。

python 复制代码
pip install flask-sqlalchemy

创建和管理数据库

模型是数据库表的 Python 类,每个模型类代表数据库中的一张表。

app.py

python 复制代码
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
import sys

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///mydatabase.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)

# OMR
class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(80), unique=True, nullable=False)
    email = db.Column(db.String(120), unique=True, nullable=False)

    def __repr__(self):
        return f'<User {self.username}>'

@app.route('/')
def index():
    return 'Hello, World!'
    
@app.route('/table')
def table():
    # 检查是否数据库是否已经有对应的数据表
    result = ""
    connection = db.engine.connect()
    if not db.engine.dialect.has_table(connection, 'user'):
        with app.app_context():
            db.create_all()
            result = "Table 'user' created successfully."
    else:
        result = "Table 'user' already exists."
    connection.close()
    return result

if __name__ == '__main__':
    port = sys.argv[1] if len(sys.argv) > 1 else 5001
    app.run(port=int(port),debug=True)

启动服务 python Flask/06/app.py

发现../..会创建一个instance目录,用浏览器访问table路径,第一次会显示

Table 'user' created successfully.

后面刷新会显示

Table 'user' already exists.

然后在instance目录下会生成mydatabase.db的文件

用终端打开该文件,.tables确认数据库中有user表,.schema users显示表结构与代码中的设置能匹配

基本的CURD操作

创建记录
python 复制代码
@app.route('/add_user')
def add_user():
    new_user = User(username='john_doe', email='[email protected]')
    db.session.add(new_user)
    db.session.commit()
    return 'User added!'

会报错,修改app.py

python 复制代码
new_user = User()
new_user.username = username
new_user.email = email
读取记录
python 复制代码
@app.route('/get_users')
def get_users():
    users = User.query.all()  # 获取所有用户
    return '<br>'.join([f'{user.username} ({user.email})' for user in users])

User.query.all():查询所有用户记录。

更新记录
python 复制代码
@app.route('/update_user/<int:user_id>')
def update_user(user_id):
    user = User.query.get(user_id)
    if user:
        user.username = '新名字'
        db.session.commit()
        return 'User updated!'
    return 'User not found!'

User.query.get(user_id):通过主键查询单个用户记录。

更新字段值并提交事务。

删除记录
python 复制代码
@app.route('/delete_user/<int:user_id>')
def delete_user(user_id):
    user = User.query.get(user_id)
    if user:
        db.session.delete(user)
        db.session.commit()
        return 'User deleted!'
    return 'User not found!'

先输入个错误的2

输入正确的id,1

删除成功, 检查数据库表也删除了

恢复数据多添加几个User数据,报错了

sh 复制代码
IntegrityError
sqlalchemy.exc.IntegrityError: (sqlite3.IntegrityError) UNIQUE constraint failed: user.email
[SQL: INSERT INTO user (username, email) VALUES (?, ?)]
[parameters: ('john_doe', '[email protected]')]
(Background on this error at: https://sqlalche.me/e/20/gkpj)

因为原来添加时都加了 unique 唯一性的键

复制代码
username = db.Column(db.String(80), unique=True, nullable=False)    
email = db.Column(db.String(120), unique=True, nullable=False)

app.py 加个时间戳

python 复制代码
...
import time
...
@app.route('/add_user')
def add_user():
    timestamp = time.time()
    username = f'john_doe_{timestamp}'
    email = f'john_{timestamp}@example.com'
    new_user = User(username=username, email=email)
    db.session.add(new_user)
    db.session.commit()
    return 'User added!'
查询操作

SQLAlchemy 提供了丰富的查询功能,可以通过查询对象来执行各种查询操作。

app.py 查询操作

python 复制代码
@app.route('/query/<username>')
def query(username):
    print(f"username: {username}")
    user = User.query.filter_by(username=username).first()
    if user:
        return f"User:{user.username} ({user.email})"
    return 'User not found!'

app.py 复杂查询

python 复制代码
...
from sqlalchemy import or_
...

@app.route('/query2/<username>/<email>')
def query2(username,email):
    print(f"username: {username}")
    print(f"email: {email}")
    user = User.query.filter(or_(User.username == username, User.email == email)).first()
    if user:
        return f"User:{user.username} ({user.email})"
    return 'User not found!'

app.py 排序与分页

python 复制代码
@app.route('/query3')
def query3():
    users = User.query.order_by(User.username).paginate(page=1, per_page=10)
    if users:
        return '<br>'.join([f'{user.username} ({user.email})' for user in users.items])
    return 'Users not found!'

使用 Flask-Migrate 进行迁移

Flask-Migrate 是一个用于数据库迁移的扩展,基于 Alembic,可以帮助你管理数据库的版本控制。

shell 复制代码
pip install flask-migrate
# 或pip3 install flask-migrate

配置 Flask-Migrate

app.py

python 复制代码
from flask_migrate import Migrate

migrate = Migrate(app, db)

初始化迁移

shell 复制代码
flask db init

app.py同级的终端目录下执行该命令

会生成migrations目录

创建迁移脚本

sh 复制代码
flask db migrate -m "Initial migration."

应用完成后,生成的DB文件

表结构有的,但是数据是没有的,要重新导数据?

执行原始SQL

python 复制代码
...
from sqlalchemy import text
...

@app.route('/raw_sql')
def raw_sql():
    result = db.session.execute(text('SELECT * FROM user'))
    return '<br>'.join([str(row) for row in result])

db.session.execute():执行原始 SQL 查询。里面的SQL语句要加text 包装下

参考

  1. Flask数据库操作
相关推荐
写代码的小王吧28 分钟前
【安全】Web渗透测试(全流程)_渗透测试学习流程图
linux·前端·网络·学习·安全·网络安全·ssh
longlong int2 小时前
【每日算法】Day 16-1:跳表(Skip List)——Redis有序集合的核心实现原理(C++手写实现)
数据库·c++·redis·算法·缓存
虾球xz2 小时前
游戏引擎学习第208天
学习·游戏引擎
小军要奋进2 小时前
httpx模块的使用
笔记·爬虫·python·学习·httpx
baobao17676408302 小时前
Mysql 数据库编程技术01
数据库·mysql·oracle
一 乐2 小时前
实验室预约|实验室预约小程序|基于Java+vue微信小程序的实验室预约管理系统设计与实现(源码+数据库+文档)
java·数据库·微信小程序·小程序·毕业设计·论文·实验室预约小程序
极限实验室2 小时前
INFINI Labs 产品更新 | Coco AI 0.3 发布 – 新增支持 Widget 外部站点集成
数据库·搜索引擎
我科绝伦(Huanhuan Zhou)2 小时前
MySQL数据库如何在线修改表结构及字段类型?
数据库·mysql
独行soc2 小时前
2025年渗透测试面试题总结- 某四字大厂面试复盘扩展 一面(题目+回答)
java·数据库·python·安全·面试·职场和发展·汽车
rockmelodies3 小时前
【MongoDB + 向量搜索引擎】MongoDB Atlas 向量搜索 提供全托管解决方案
数据库·mongodb·搜索引擎