3. Flask操作数据库
1. 连接数据库
首先下载 MySQL数据库
其次下载对应的包:
pip install pymysql
pip install flask-sqlalchemy
在 app.py 中进行连接测试
from flask import Flask, request, render_template
from flask_sqlalchemy import SQLAlchemy
hostname = "127.0.0.1"
port = 3306
username = "root"
password = "root"
database = "flask_learn"
# 在 app.config 中设置连接数据库的信息
app.config['SQLALCHEMY_DATABASE_URI'] = f"mysql+pymysql://{username}:{password}@{hostname}:{port}/{database}?charset=utf8mb4"
# 使用SQLAlchemy(app)创建一个db对象
# 此时SQLAlchemy辉自动读取app.config中连接数据库的信息
db = SQLAlchemy(app)
with app.app_context():
with db.engine.connect() as conn:
rs = conn.execute("select 1")
print(rs.fetchone()) # 输出1说明连接成功, 0说明连接不成功
if __name__ == '__main__':
app.run(debug=True)
2. ORM模型与表的映射(直接使用代码操作数据库)
在app.py中:
# 定义User类
class User(db.Model):
# 声明该实体类和数据库中的user表对应
__tablename__ = "user"
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
username = db.Column(db.String(100), nullable=False)
password = db.Column(db.String(100), nullable=False)
with app.app_context():
db.create_all() # 创建表
3. ORM的CRUD操作
在 app.py 中, 对 user 表进行 CRUD 操作
3.1 添加数据
# ORM的CRUD操作
@app.route('/user/add')
def add_user():
# 1. 创建ORM对象
user = User(username = '111', password = '111')
# 2. 将ORM对象添加到 db.session 中
db.session.add(user)
# 3. 将db.session 同步到数据库中
db.session.commit()
return "添加用户成功"
3.2 查找数据
根据主键查找
@app.route('/user/query')
def query_user():
# 1. 根据主键查找
user = User.query.get(1)
print(user.username, user.password)
return "查找用户成功"
filter_by 查找
@app.route('/user/query2')
def query_user2():
# 2. filter_by 查找
# 返回值是Query数组
users = User.query.filter_by(username = '111')
for user in users:
print(user.username, user.password)
return "查找用户成功"
3.3 更新数据
@app.route('/user/update')
def update_user():
user = User.query.filter_by(username = '111').first()
user.password = '222'
db.session.commit()
return "更新用户成功"
3.4 删除数据
@app.route('/user/delete')
def delete_user():
# 1. 根据主键查找
user = User.query.get(1)
db.session.delete(user)
db.session.commit()
return "删除用户成功"
4. ORM中外键与数据库表的关系
假设,一个用户可以发表多篇文章,用户与文章是一对多的关系,因此在 article 表中有外键 author_id 对应 user的 id
定义用户类 user 与文章类 article 如下:
# 定义User类
class User(db.Model):
# 声明该实体类和数据库中的user表对应
__tablename__ = "user"
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
username = db.Column(db.String(100), nullable=False)
password = db.Column(db.String(100), nullable=False)
# 创建user表与article表之间的关联关系, 从而可以使得User的对象user通过 user.articles 获得对应的 article 对象的列表 articles
articles = db.relationship("Article", back_populates="author")
class Article(db.Model):
__tablename__ = "article"
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
title = db.Column(db.String(200), nullable=False)
content = db.Column(db.Text, nullable=False)
# 添加文章对应的作者的外键
author_id = db.Column(db.Integer, db.ForeignKey("user.id"))
# 创建两个表之间的关联关系, 从而可以使得Article的对象article通过 article.author 获得对应的 user 对象
author = db.relationship("User", back_populates="articles")
关联两个表的另一种方式:
# 定义User类
class User(db.Model):
# 声明该实体类和数据库中的user表对应
__tablename__ = "user"
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
username = db.Column(db.String(100), nullable=False)
password = db.Column(db.String(100), nullable=False)
class Article(db.Model):
__tablename__ = "article"
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
title = db.Column(db.String(200), nullable=False)
content = db.Column(db.Text, nullable=False)
# 添加文章对应的作者的外键
author_id = db.Column(db.Integer, db.ForeignKey("user.id"))
# 创建两个表之间的关联关系, 从而可以使得Article的对象article通过 article.author 获得对应的 user 对象, 同时 user 会 自动与article 关联, 通过 user.articles 获得对应的 article 对象的列表 articles
author = db.relationship("User", backref="articles")
查询某个用户的所有文章:
@app.route('/article/add')
def add_article():
article1 = Article(title="aaa", content="aaaaaaaaaaaa")
article1.author = User.query.get(2)
article2 = Article(title="bbb", content="bbbbbbbbbbbb")
article2.author = User.query.get(2)
# 添加到session中
db.session.add_all([article1, article2])
db.session.commit()
return "添加文章成功"
@app.route('/articles/query')
def query_articles():
# 查找某用户的所有文章
user = User.query.get(2)
articles = user.articles
for article in articles:
print(article.title, article.content, article.author.username)
return "查找用户id为2的所有文章成功"
5. 数据库表中字段改变
首先安装包 flask-migrate
pip install flask-migrate
然后在 app.py 中
from flask_migrate import Migrate
hostname = "127.0.0.1"
port = 3306
username = "root"
password = "root"
database = "flask_learn"
# 在 app.config 中设置连接数据库的信息
app.config['SQLALCHEMY_DATABASE_URI'] = f"mysql+pymysql://{username}:{password}@{hostname}:{port}/{database}?charset=utf8mb4"
# 使用SQLAlchemy(app)创建一个db对象
# 此时SQLAlchemy辉自动读取app.config中连接数据库的信息
db = SQLAlchemy(app)
migrate = Migrate(app, db)
接下来需要将整个项目的所有 ORM实体类 映射到 数据库表中
-
在控制台执行
flask db init
(一个项目执行一次)执行结果:
-
在控制台执行
flask db migrate
, 识别ORM模型的改变(即识别字段的增删), 生成迁移脚本迁移脚本在 migrate文件夹下的version文件夹下
-
在控制台执行
flask db upgrade
, 运行迁移脚本,同步到数据库中
-
只要后端代码对ORM模型(即实体类的属性)进行改变,就需要执行 2和3,从而将其映射到数据库中,使得数据库中的对应字段进行改变