这里选择学生表和班级表作为案例
app.py
from App import create_app
app = create_app()
if __name__ == '__main__':
app.run(debug=True)
# 运行: flask run --debug
views.py
import random
from flask import Blueprint, request, render_template
from .models import *
#创建蓝图(路由)
blue = Blueprint('user', __name__)
@blue.route('/')
def index():
return 'index'
# 多表操作 - 增删改查
#一对多
# 1.增加
#添加班级
@blue.route('/addgrade/')
def add_grade():
#先添加班级
grades = []
for i in range(10):
grade = Grade() #创建班级对象
grade.name = f'三年 - {str(random.randint(10, 99))}班'
grades.append(grade)
try:
db.session.add_all(grades)
db.session.commit()
except Exception as e:
print(e)
db.session.rollback()
db.session.flush()
return '添加成功'
#添加学生
@blue.route('/addstu/')
def add_stu():
#先添加班级
students = []
for i in range(10):
stu = Student()
stu.name = f'小新{i}'
stu.age = i
stu.gradeid = random.randint(10, 11)
students.append(stu)
try:
db.session.add_all(students)
db.session.commit()
except Exception as e:
print(e)
db.session.rollback()
db.session.flush()
return '添加成功'
# 修改
@blue.route('/updatestu/')
def update_stu():
stu = Student.query.first()
stu.age = 100
db.session.commit()
return '修改成功'
# 删除
# 删除学生
@blue.route('/delstu/')
def del_stu():
stu = Student.query.first()
db.session.delete(stu)
db.session.commit()
return '删除成功'
# 删除班级
@blue.route('/delgrade/')
def del_grade():
# filter_by 和 filter 都返回的是查询对象,需要通过 .first(), .all(), .scalar(), 等方法来获取实际的数据
# grade = Grade.query.get(10) #get() 根据主键查询
grade = Grade.query.filter_by(id=11).first() #这里使用filter()查询必须要.first()或其他条件
print(grade.id)
# db.session.delete(grade)
# db.session.commit()
# 当删除班级后、与之相关联的学生表的gradeid字段的数据会变为null
return '删除成功'
# 查询
@blue.route('/getstu/')
def get_stu():
# 查询某个学生所在的班级: 反向引用grade
stu = Student.query.get(3)
print(stu.name, stu.age)
print(stu.gradeid, stu.grade, stu.grade.name, stu.grade.id)
#查询某个班级下的所有学生
grade = Grade.query.get(11)
print(grade.name)
print(grade.students) # 查询班级下的所有学生
for stu in grade.students: # 遍历班级下的所有学生
print(stu.name, stu.age)
return '查询成功'
models.py
注意:要执行数据初始化和迁移的操作
1.flask db init
2.flask db migrate
3.flask db upgrade
# 模型数据库
from .exts import db #导入db对象
# 模型 对应数据库中的 数据库
# 类名 表 (对表操作就是对类操作)
# 对象(变量值) 表的一行数据
# 类属性(变量名) 表字段
# 创建对象: 对象名(自定义) = 类名()
# 对象.属性名 = 表字段的值
'''
多表关系:
一对多
班级:学生 = 1:N
'''
# 模型: 类名
# 必须继承:db.Model 才是 一个模型
#班级表
class Grade(db.Model):
# 表名
__tablename__ = 'grade'
# 字段
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
name = db.Column(db.String(50), unique=True)
# 建立关联
# 第一个参数是关联的模型名(类名)
# 第二个参数是反向引用的名称,grade对象、让student反过来得到grade对象的名称:student.grade
# 第三个参数:懒加载,当调用时才去加载
# 这里的students不是字段、就是一个类属性
students = db.relationship('Student', backref='grade', lazy=True)
# 打印对象的名字
# def __repr__(self):
# return self.id, self.name # 返回对象的名字
# 学生表
class Student(db.Model):
__tablename__ = 'student'
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
name = db.Column(db.String(50), unique=True)
age = db.Column(db.Integer)
# 外键、要和Grade表中的id字段关联
gradeid = db.Column(db.Integer, db.ForeignKey(Grade.id)) #类型要和Grade表中的id字段的一样
# db.Column :表示字段
# db.Integer :表示字段的类型 整数类型
# primary_key=true : 表示主键
# autoincrement=true : 表示自增
# db.String(50) : 表示字段的长度 相当于varchar(50)
# index=True : 表示创建索引
# db.Boolean : 表示布尔类型
# default=1 : 表示默认值
# db.Float : 表示浮点类型
# nullable=False : 表示不能为空
exts.py
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
#初始化插件
db = SQLAlchemy()
migrate = Migrate()
#和app对象绑定
def init_exts(app):
db.init_app(app)
migrate.init_app(app,db)
__init__.py
from flask import Flask
from .views import blue
from .exts import init_exts
def create_app():
app = Flask(__name__) # 创建flask应用
#注册蓝图
app.register_blueprint(blueprint=blue)
#配置数据库
db_uri = 'sqlite:///sqlite3.db' #sqlite的配置
# db_uri = 'mysql+pymysql://root:[email protected]:3306/flask_db?charset=utf8mb4' #mysql的配置
app.config['SQLALCHEMY_DATABASE_URI'] = db_uri
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
#初始化插件
init_exts(app=app)
return app