Flask-SQLAlchemy 是 Flask 框架的一个扩展,它将强大的 SQLAlchemy ORM(对象关系映射)工具与 Flask 无缝集成,简化了在 Flask 应用中操作数据库的流程。通过它,你可以用 Python 类(模型)映射数据库表,用类方法和属性替代 SQL 语句,实现数据库的增删改查(CRUD)操作,无需直接编写原生 SQL。
一、Flask-SQLAlchemy 安装
首先通过 pip 安装扩展:
pip install flask-sqlalchemy
二、核心概念与配置
1. 基本概念
- ORM(对象关系映射):将数据库表映射为 Python 类(称为“模型”),表的列映射为类的属性,表的行映射为类的实例。
- 会话(Session):SQLAlchemy 通过会话(
db.session)管理数据库操作,所有增删改查都需通过会话提交后才会生效。 - 模型(Model):继承自
db.Model的 Python 类,对应数据库中的一张表。
2. 数据库配置
在 Flask 应用中,需先配置数据库连接信息(如数据库类型、地址、账号密码等),支持 SQLite、MySQL、PostgreSQL 等主流数据库。
配置格式:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
# 配置数据库连接 URI(不同数据库格式不同)
# 1. SQLite(无需额外服务,文件型数据库,适合开发测试)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///mydb.db' # 数据库文件存当前目录
# 2. MySQL(需提前安装 MySQL 服务器,依赖 pymysql 驱动)
# app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://用户名:密码@主机:端口/数据库名'
# 示例:'mysql+pymysql://root:123456@localhost:3306/flask_db'
# 3. PostgreSQL(需安装 PostgreSQL 服务器,依赖 psycopg2 驱动)
# app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://用户名:密码@主机:端口/数据库名'
# 禁用 SQLAlchemy 的修改跟踪功能(提高性能,可选)
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
# 初始化 SQLAlchemy 实例(关联 Flask 应用)
db = SQLAlchemy(app)
三、定义模型(数据库表)
模型是 Python 类,继承自 db.Model,类的属性对应表的列。每个属性通过 db.Column 定义,需指定数据类型和约束(如主键、非空、唯一等)。
1. 基本模型示例(用户表)
# 定义 User 模型(对应数据库中的 users 表)
class User(db.Model):
# 表名(默认是类名小写,可自定义)
__tablename__ = 'users'
# 列定义:db.Column(类型, 约束)
id = db.Column(db.Integer, primary_key=True, autoincrement=True) # 主键,自增
username = db.Column(db.String(50), unique=True, nullable=False) # 用户名,唯一,非空
email = db.Column(db.String(100), unique=True, nullable=False) # 邮箱,唯一,非空
age = db.Column(db.Integer, default=0) # 年龄,默认值 0
# 可选:定义 __repr__ 方法,方便打印实例信息
def __repr__(self):
return f'<User {self.username}>'
2. 常用数据类型
| SQLAlchemy 类型 | 对应数据库类型 | 说明 |
|---|---|---|
db.Integer |
INT | 整数 |
db.String(length) |
VARCHAR(length) | 字符串(指定长度) |
db.Text |
TEXT | 长文本(无长度限制) |
db.Boolean |
BOOLEAN | 布尔值(True/False) |
db.DateTime |
DATETIME | 日期时间(需用 datetime 模块) |
db.Float |
FLOAT | 浮点数 |
db.ForeignKey |
FOREIGN KEY | 外键(用于关联表) |
四、创建数据库和表
定义模型后,需通过 db.create_all() 创建数据库文件和表结构(仅首次需要)。
1. 创建表结构
# 在应用上下文(App Context)中执行创建操作
with app.app_context():
db.create_all() # 检查并创建所有模型对应的表
print("数据库和表创建成功")
- 执行后,SQLite 会在当前目录生成
mydb.db文件;MySQL/PostgreSQL 会在指定数据库中创建users表。 - 若模型已修改(如新增字段),直接调用
db.create_all()不会更新表结构,需用迁移工具(见后文)。
五、数据库操作(CRUD)
所有操作需通过 db.session 执行,最终用 db.session.commit() 提交事务(写入数据库)。
1. 创建(Create):新增数据
with app.app_context():
# 1. 创建用户实例(对应表中的一行)
user1 = User(username='张三', email='zhangsan@example.com', age=25)
user2 = User(username='李四', email='lisi@example.com') # age 用默认值 0
# 2. 将实例添加到会话
db.session.add(user1) # 添加单个
db.session.add_all([user2]) # 批量添加
# 3. 提交会话(写入数据库)
db.session.commit()
print("数据新增成功")
2. 读取(Read):查询数据
SQLAlchemy 提供丰富的查询方法,通过 模型名.query 发起查询。
with app.app_context():
# 1. 查询所有用户
all_users = User.query.all()
print("所有用户:", all_users) # 输出 __repr__ 定义的格式
# 2. 按条件查询(filter_by:简单条件,参数为关键字参数)
user_zhangsan = User.query.filter_by(username='张三').first() # 取第一个结果
print("张三的邮箱:", user_zhangsan.email)
# 3. 更复杂的条件(filter:支持表达式,如大于、包含等)
# 示例:查询年龄 > 20 的用户
adults = User.query.filter(User.age > 20).all()
print("年龄>20的用户:", adults)
# 4. 按主键查询(get 方法,效率最高)
user_id1 = User.query.get(1) # 查询 id=1 的用户
print("id=1的用户:", user_id1)
# 5. 排序(order_by)和限制数量(limit)
# 示例:按年龄升序,取前 2 个用户
sorted_users = User.query.order_by(User.age).limit(2).all()
print("按年龄排序的前2用户:", sorted_users)
3. 更新(Update):修改数据
with app.app_context():
# 1. 先查询要修改的用户
user = User.query.filter_by(username='李四').first()
if user:
# 2. 修改属性
user.age = 30
user.email = 'new_lisi@example.com'
# 3. 提交会话(保存修改)
db.session.commit()
print("数据更新成功")
4. 删除(Delete):删除数据
with app.app_context():
# 1. 先查询要删除的用户
user = User.query.filter_by(username='张三').first()
if user:
# 2. 从会话中删除
db.session.delete(user)
# 3. 提交会话(执行删除)
db.session.commit()
print("数据删除成功")
六、表关系(一对多示例)
实际应用中,表之间常有关联(如“用户-帖子”:一个用户可发多个帖子)。通过 db.relationship 和 db.ForeignKey 定义关系。
1. 定义关联模型(帖子表)
class Post(db.Model):
__tablename__ = 'posts'
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
title = db.Column(db.String(100), nullable=False)
content = db.Column(db.Text)
# 外键:关联 users 表的 id 列(user_id 是 posts 表的外键)
user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False)
# 关系属性:通过 post.author 可访问该帖子的作者(User 实例)
# backref='posts':在 User 模型中添加 posts 属性,通过 user.posts 访问该用户的所有帖子
author = db.relationship('User', backref=db.backref('posts', lazy=True))
def __repr__(self):
return f'<Post {self.title}>'
2. 使用关联关系
with app.app_context():
# 1. 创建用户和关联的帖子
user = User.query.get(2) # 假设 id=2 是李四
post1 = Post(title='我的第一篇帖子', content='Hello World', author=user)
post2 = Post(title='第二篇帖子', content='Flask 学习', user_id=user.id) # 也可直接指定 user_id
db.session.add_all([post1, post2])
db.session.commit()
# 2. 通过用户访问其所有帖子(user.posts)
print(f"{user.username} 的帖子:")
for post in user.posts:
print(f"- {post.title}")
# 3. 通过帖子访问其作者(post.author)
post = Post.query.get(1)
print(f"帖子《{post.title}》的作者:{post.author.username}")
七、数据库迁移(Flask-Migrate)
当模型修改(如新增字段、修改类型)时,直接用 db.create_all() 无法更新表结构,需用 Flask-Migrate 扩展管理数据库迁移(类似 Git 版本控制)。
1. 安装与初始化
pip install flask-migrate
from flask_migrate import Migrate
# 初始化迁移工具(关联 app 和 db)
migrate = Migrate(app, db)
2. 迁移命令(终端执行)
# 1. 初始化迁移环境(仅首次执行,生成 migrations 文件夹)
flask db init
# 2. 生成迁移脚本(检测模型与数据库的差异)
flask db migrate -m "描述信息(如:新增 age 字段)"
# 3. 应用迁移(更新数据库表结构)
flask db upgrade
- 若需回滚到上一版本:
flask db downgrade
八、最佳实践
- 应用上下文:Flask-SQLAlchemy 操作需在 应用上下文 中执行(通过
with app.app_context():或在视图函数中,因视图函数默认运行在上下文内)。 - 避免硬编码配置:数据库账号密码等敏感信息应放在环境变量或配置文件中(如
.env),而非直接写在代码里。 - 生产环境数据库:开发用 SQLite 方便,但生产环境建议用 MySQL 或 PostgreSQL(支持高并发、数据持久化更可靠)。
- 事务管理:复杂操作(如多表修改)需确保原子性,失败时用
db.session.rollback()回滚。
总结
Flask-SQLAlchemy 简化了 Flask 应用的数据库操作:
- 通过 模型类 映射数据库表,无需编写原生 SQL。
- 用 db.session 管理 CRUD 操作,commit() 提交事务。
- 支持表关系(一对多、多对多等),通过 relationship 实现关联查询。
- 配合 Flask-Migrate 处理模型变更,确保数据库结构同步。
掌握它后,可高效开发需要数据库支持的 Flask 应用(如用户系统、博客、电商平台等)。
SQLalchemy
demo01_sqlalchemy.py
"""
数据库操作流程
- 1. 安装扩展
- pip install flask-sqlalchemy
- pip install flask-mysqldb / pymysql
- 2. 设置数据库的配置信息
- 3. 创建 sqlalchemy 对象 db,关联 app
- 4. 编写模型类,继承自 db.Model
- 5. 操作数据库
- 增删改
- 查询
"""
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
# 2. 设置数据库的配置信息
# mysql://[用户名]:[密码]@[主机地址][端口号]/[数据库名]
app.config["SQLALCHEMY_DATABASE_URI"] = "mysql://root:123456@127.0.0.1:3306/data36"
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
# 3. 创建 sqlalchemy 对象 db,关联 app
db = SQLAlchemy(app)
# 4. 编写模型类,继承自 db.Model
class Student(db.Model): # 默认表名为 student
# 【主键】 参数1:表示 id 的类型;参数2:表示 id 的约束类型
__tablename__ = "person" # 手动设置表名
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(32))
@app.route("/")
def helloworld():
return "hello world Flask"
if __name__ == "__main__":
# 创建数据库的表,创建的是继承自 db.Model 的表
with app.app_context():
# 创建所有继承自db.Model的表
db.create_all()
# 删除所有继承自db.Model的表
# db.drop_all()
app.run(debug=True)
CRUD
demo02_CRUD.py
"""
增删改查
- 全部都是 db.session 操作
- 常见方法:
- db.session.add(obj) 添加单个对象
- db.session.add_all([obj1, obj2]) 添加多个对象
- db.session.delete(obj) 删除单个对象
- db.session.commit() 提交会话
- db.drop_all() 删除继承自 db.Model 的所有表
- db.create_all() 创建继承自 db.Model 的所有表
- db.session.rollback() 回滚
- db.session.remove() 移除会话
- 如果想要打印一个对象的时候想看到指定信息,那么请重写 __repr__ 方法
"""
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
# 2. 设置数据库的配置信息
# mysql://[用户名]:[密码]@[主机地址][端口号]/[数据库名]
app.config["SQLALCHEMY_DATABASE_URI"] = "mysql://root:123456@127.0.0.1:3306/data36"
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
# 3. 创建 sqlalchemy 对象 db,关联 app
db = SQLAlchemy(app)
# 4. 编写模型类,继承自 db.Model
# 角色【一方】
class Role(db.Model): # 默认表名为 student
# 【主键】 参数1:表示 id 的类型;参数2:表示 id 的约束类型
__tablename__ = "roles" # 手动设置表名
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(32))
# 用户【多方】
class User(db.Model): # 默认表名为 student
# 【主键】 参数1:表示 id 的类型;参数2:表示 id 的约束类型
__tablename__ = "users" # 手动设置表名
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(32))
# 建立外键
role_id = db.Column(db.Integer, db.ForeignKey(Role.id))
@app.route("/")
def helloworld():
return "hello world Flask"
def add():
role = Role(name="role")
db.session.add(role)
db.session.commit()
user = User(name="user", role_id=role.id)
db.session.add(user)
db.session.commit()
if __name__ == "__main__":
# 创建数据库的表,创建的是继承自 db.Model 的表
with app.app_context():
# 创建所有继承自db.Model的表
db.create_all()
# 删除所有继承自db.Model的表
# db.drop_all()
add()
app.run(debug=True)
查询
demo03_select.py
"""
查询
xxx.query.[过滤器].[执行器]
- 查询过滤器【可选】
- filter()
- filter_by()
- limit
- offset()
- order_by()
- group_by()
- 查询执行器【必选】
- all()
- first()
- first_or_404()
- get()
- get_or_404()
- count()
# page: 表示要查询的页数;per_page: 表示每页有多少条数据;
# Error_out: False查不到不会报错;会返回 paginate 对象
- paginate(page, per_page, Error_out) # 分页
# paginate.pages 总页数
# paginate.page 当前页
# paginate.items 当前的对象列表
"""
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
# 2. 设置数据库的配置信息
# mysql://[用户名]:[密码]@[主机地址][端口号]/[数据库名]
app.config["SQLALCHEMY_DATABASE_URI"] = "mysql://root:123456@127.0.0.1:3306/data36"
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
# 3. 创建 sqlalchemy 对象 db,关联 app
db = SQLAlchemy(app)
# 4. 编写模型类,继承自 db.Model
# 角色【一方】
class Role(db.Model): # 默认表名为 student
# 【主键】 参数1:表示 id 的类型;参数2:表示 id 的约束类型
__tablename__ = "roles" # 手动设置表名
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(32))
# 用户【多方】
class User(db.Model): # 默认表名为 student
# 【主键】 参数1:表示 id 的类型;参数2:表示 id 的约束类型
__tablename__ = "users" # 手动设置表名
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(32))
# 建立外键
role_id = db.Column(db.Integer, db.ForeignKey(Role.id))
@app.route("/")
def helloworld():
return "hello world Flask"
def add():
role = Role(name="role")
db.session.add(role)
db.session.commit()
user = User(name="user", role_id=role.id)
db.session.add(user)
db.session.commit()
if __name__ == "__main__":
# 创建数据库的表,创建的是继承自 db.Model 的表
with app.app_context():
# 创建所有继承自db.Model的表
# db.create_all()
# 删除所有继承自db.Model的表
# db.drop_all()
pass
add()
app.run(debug=True)
图书馆案例
demo04_library.py
"""
图书馆案例
- 1. 数据库配置
- 作者模型【一方】
- 书籍模型【多方】
- 2. 添加测试数据
- 3. 添加作者、书籍
- 4. 删除作者、删除书籍
"""
from flask import Flask, render_template, request, redirect, flash
from flask_sqlalchemy import SQLAlchemy
from flask_wtf.csrf import CSRFProtect
app = Flask(__name__)
# 设置密钥
app.config["SECRET_KEY"] = "dsfsdfasdfa"
# 使用 CSRFProtect 保护 app
CSRFProtect(app)
# 1. 设置数据库的配置信息
# mysql://[用户名]:[密码]@[主机地址][端口号]/[数据库名]
app.config["SQLALCHEMY_DATABASE_URI"] = "mysql://root:123456@127.0.0.1:3306/library"
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
# 2. 创建 sqlalchemy 对象,关联app
db = SQLAlchemy(app)
# 3. 作者模型类
# 作者模型【一方】
class Author(db.Model): # 默认表名为 student
# 【主键】 参数1:表示 id 的类型;参数2:表示 id 的约束类型
__tablename__ = "authors" # 手动设置表名
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(32))
# 关系属性
# 查看作者名下的书籍:Author.books
# 查看书籍背后的作者:Book.author
books = db.relationship("Book", backref="author")
# 4. 书籍模型类
# 书籍模型【多方】
class Book(db.Model): # 默认表名为 student
# 【主键】 参数1:表示 id 的类型;参数2:表示 id 的约束类型
__tablename__ = "books" # 手动设置表名
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(32))
# 建立外键
author_id = db.Column(db.Integer, db.ForeignKey(Author.id))
# 等价语句:author_id = db.Column(db.Integer, db.ForeignKey("authors.id"))
@app.route("/")
def show_index():
# 1. 查询所有作者的信息
authors = Author.query.all()
# 2. 携带作者的信息,渲染页面
response = render_template("Cdemo01_library.html", authors=authors)
return response
"""
添加数据的逻辑
作者不存在,则添加数据
作者存在,书籍存在,不添加数据
作者存在,书籍不存在,添加数据
"""
# 添加书籍
@app.route("/add_data", methods=["POST", "GET"])
def add_data():
# 1. 获取提交的数据
author_name = request.form.get("author")
book_name = request.form.get("book")
# 判断输入的数据是否为空
if not all([author_name, book_name]):
flash("作者或书籍不能为空!")
return redirect("/")
# 2. 携带作者的信息,渲染页面
author = Author.query.filter(Author.name == author_name).first()
# 3.判断作者是否存在
if author:
# 4. 通过书籍名称查询书籍对象
book = Book.query.filter(
# 判断作者是否写过该书
Book.name == book_name,
Book.author_id == author.id,
).first()
# 5. 判断书籍对象是否存在
if book:
flash(f"{author_name}已经写了《{book_name}》")
else:
# 创建书籍对象,添加到数据库
book_adding = Book(name=book_name, author_id=author.id)
db.session.add(book_adding)
db.session.commit()
else:
# 创建作者对象,添加到数据库
author_adding = Author(name=author_name)
db.session.add(author_adding)
db.session.commit()
# 创建书籍对象,添加到数据库
book_adding = Book(name=book_name, author_id=author_adding.id)
db.session.add(book_adding)
db.session.commit()
return redirect("/")
# 删除书籍
@app.route("/del_data/<int:book_id>", methods=["POST", "GET"])
def del_data(book_id):
# 根据书籍编号取出书籍对象
book = Book.query.get(book_id)
# 删除该书籍对象
db.session.delete(book)
db.session.commit()
# 重定向到显示页面
return redirect("/")
# 删除书籍
@app.route("/del_author/<int:author_id>", methods=["POST", "GET"])
def del_author(author_id):
# 根据作者编号取出作者对象
author = Author.query.get(author_id)
# 删除作者名下所有书籍
for book in author.books:
db.session.delete(book)
# 删除该作者对象
db.session.delete(author)
db.session.commit()
# 重定向到显示页面
return redirect("/")
if __name__ == "__main__":
# 为了演示方便,先删除后创建
# 创建数据库的表,创建的是继承自 db.Model 的表
with app.app_context():
# 删除所有继承自db.Model的表
db.drop_all()
# 创建所有继承自db.Model的表
db.create_all()
# 添加测试数据
# 生成作者数据
au1 = Author(name="金庸")
au2 = Author(name="古龙")
au3 = Author(name="莫言")
# 把数据提交给用户会话
db.session.add_all([au1, au2, au3])
# 提交会话
db.session.commit()
# 生成书籍数据
bk1 = Book(name="笑傲江湖", author_id=au1.id)
bk2 = Book(name="神雕侠侣", author_id=au1.id)
bk3 = Book(name="欢乐英雄", author_id=au2.id)
bk4 = Book(name="白玉老虎", author_id=au2.id)
bk5 = Book(name="丰乳肥臀", author_id=au3.id)
bk6 = Book(name="红高粱家族", author_id=au3.id)
# 把数据提交给用户会话
db.session.add_all([bk1, bk2, bk3, bk4, bk5, bk6])
# 提交会话
db.session.commit()
app.run(debug=True)
templates/Cdemo01_library.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>library</title>
</head>
<body>
<form action="add_data" , method="post">
{# 设置隐藏字段csrf_token,
只要使用了CSRFProtect,然后使用模板渲染时可以直接使用csrf_token() 方法 #}
<input type="hidden" name="csrf_token" value="{{csrf_token()}}">
作者:<input type="text" name="author"><br>
书籍:<input type="text" name="book"><br>
<input type="submit" value="添加"><br>
{% for message in get_flashed_messages() %}
<span style="color: red;">{{message}}</span>
{% endfor %}
</form>
<hr>
{# 数据展示 #}
<ul>
{% for author in authors %}
<!-- <li>作者:{{ author.name }} <a href="/del_author/{{author.id}}">删除</a> </li> -->
<li>作者:{{ author.name }} <a href="{{url_for('del_author', author_id = author.id)}}">删除</a> </li>
<ul>
{% for book in author.books %}
<li>书籍:{{book.name}} <a href="/del_data/{{book.id}}">删除</a> </li>
{% endfor %}
</ul>
{% endfor %}
</ul>
</body>
</html>
多对多
demo05_many_to_many.py
"""
多对多
案例:学生和课程
"""
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
# 2. 设置数据库的配置信息
# mysql://[用户名]:[密码]@[主机地址][端口号]/[数据库名]
app.config["SQLALCHEMY_DATABASE_URI"] = "mysql://root:123456@127.0.0.1:3306/school"
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
# 3. 创建 sqlalchemy 对象 db,关联 app
db = SQLAlchemy(app)
# 4. 编写模型类,继承自 db.Model
tb_student_course = db.Table(
"tb_student_course",
db.Column("student_id", db.Integer, db.ForeignKey("students.id")),
db.Column("course_id", db.Integer, db.ForeignKey("courses.id")),
)
class Student(db.Model):
# 【主键】 参数1:表示 id 的类型;参数2:表示 id 的约束类型
__tablename__ = "students" # 手动设置表名
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(32))
# 关系属性
# secondary:使用在多对多中,用来表示二次查询的
courses = db.relationship(
"Course", backref="students", secondary="tb_student_course"
)
class Course(db.Model):
# 【主键】 参数1:表示 id 的类型;参数2:表示 id 的约束类型
__tablename__ = "courses" # 手动设置表名
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(32))
@app.route("/")
def helloworld():
return "hello world Flask"
if __name__ == "__main__":
# 创建数据库的表,创建的是继承自 db.Model 的表
with app.app_context():
# 删除所有继承自db.Model的表
db.drop_all()
# 创建所有继承自db.Model的表
db.create_all()
# 添加测试数据
stu1 = Student(name="张三")
stu2 = Student(name="李四")
stu3 = Student(name="王五")
cou1 = Course(name="物理")
cou2 = Course(name="化学")
cou3 = Course(name="生物")
stu1.courses = [cou2, cou3]
stu2.courses = [cou2]
stu3.courses = [cou1, cou2, cou3]
db.session.add_all([stu1, stu2, stu3])
db.session.add_all([cou1, cou2, cou3])
db.session.commit()
app.run(debug=True)
数据库迁移
"""
数据库迁移
- 目的:当数据的表结构发生变化之后,如果直接删除原有的数据,再添加新的数据,有可能会导致数据丢失
- 注意点:
- 1. 是为了备份表结构,而不是数据
- 2. 如果想要备份数据,需要使用工具,navicat,mysqlworkbench……
- 操作流程
- 1. 安装扩展
- pip install flask_script
- pip install flask_migrate
- 2. 导入三个类
- from flask_script import Manager
- from install flask_migrate
- 3. 通过 Manager 类创建对象 manager,管理app
- manager = Manager(app)
- 4. 使用 Migrate,关联app,db
- Migrate(app, db)
- 5. 给manager添加一条操作命令
- manager.add_command("db", MigrateCommand)
- 相关迁移命令:
- 生成迁移文件夹:
- python xxx.py db init
- 将模型类生成迁移脚本
- python xxx.py db migrate -m '注释'
- 将迁移脚本更新到数据库中
- python xxx.py db upgrade
"""
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_script import Manager
# 导入数据迁移核心类
from flask_migrate import Migrate, MigrateCommand
app = Flask(__name__)
# 设置数据库的配置信息
# mysql://[用户名]:[密码]@[主机地址][端口号]/[数据库名]
app.config["SQLALCHEMY_DATABASE_URI"] = "mysql://root:123456@127.0.0.1:3306/flasktest"
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
# 创建 sqlalchemy 对象 db,关联 app
db = SQLAlchemy(app)
manager = Manager(app)
# 初始化数据迁移
migrate = Migrate(app, db)
# 给manager添加一条操作命令
manager.add_command("db", MigrateCommand)
# 编写模型类
class Student(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(32))
@app.route("/")
def helloworld():
return "hello world Flask"
if __name__ == "__main__":
manager.run()