# 导入必要的库和模块
import json
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy.orm import backref
from datetime import datetime
# 初始化SQLAlchemy对象和Flask应用
db = SQLAlchemy()
app = Flask(__name__, template_folder="templates", static_folder="static")
# 配置数据库连接和其他设置
app.config.update({
"DEBUG": True,
"SQLALCHEMY_DATABASE_URI": "mysql://root:123@127.0.0.1:3306/flaskdemo?charset=utf8mb4",
"SQLALCHEMY_TRACK_MODIFICATIONS": False,
"SQLALCHEMY_ECHO": True,
})
# 初始化数据库
db.init_app(app)
# 定义学生和课程之间的多对多关系表
student_and_course = db.Table(
"table_student_course",
db.Column("id", db.Integer, primary_key=True, comment="主键ID"),
db.Column("sid", db.Integer, db.ForeignKey("table_student.id"), comment="学生"),
db.Column("cid", db.Integer, db.ForeignKey("table_course.id"), comment="课程"),
db.Column("created_time", db.DateTime, default=datetime.now, comment="购买时间"),
)
# 定义学生信息模型
class Student(db.Model):
__tablename__ = "table_student"
id = db.Column(db.Integer, primary_key=True, comment="主键")
name = db.Column(db.String(15), comment="姓名")
age = db.Column(db.SmallInteger, comment="年龄")
sex = db.Column(db.Boolean, default=True, comment="性别")
email = db.Column(db.String(128), comment="邮箱地址")
money = db.Column(db.Numeric(10, 2), default=0.0, comment="钱包")
course_list = db.relationship("Course",
secondary=student_and_course,
backref="student_list",
lazy="dynamic")
def __repr__(self):
return json.dumps(self.__to_dict__, ensure_ascii=False)
@property
def __to_dict__(self):
return {
"id": self.id,
"name": self.name,
"age": self.age,
"sex": self.sex,
"email": self.email,
"money": float(self.money),
}
# 定义课程信息模型
class Course(db.Model):
__tablename__ = "table_course"
id = db.Column(db.Integer, primary_key=True, comment="主键")
name = db.Column(db.String(64), unique=True, comment="课程")
price = db.Column(db.Numeric(7, 2), default=0.0, comment="价格")
def __repr__(self):
return json.dumps(self.__to_dict__, ensure_ascii=False)
@property
def __to_dict__(self):
return {
"id": self.id,
"name": self.name,
"price": self.price,
}
# 数据库表操作路由
@app.route("/create")
def create_table():
"""创建数据库中所有模型对应的表"""
db.create_all()
return "ok"
@app.route("/drop")
def drop_table():
"""删除数据库中所有模型对应的表"""
db.drop_all()
return "ok"
# 数据操作路由
@app.route("/")
def index():
"""简单的首页路由"""
return "ok"
@app.route("/a1")
def a1():
"""添加测试数据:学生、课程及其关联关系"""
# 创建带有3门新课程的学生
student = Student(
name="xiaozhao",
age=13,
sex=False,
money=30000,
email="xiaozhao@qq.com",
course_list=[
Course(name="python入门", price=99.99),
Course(name="python初级", price=199.99),
Course(name="python进阶", price=299.99),
]
)
db.session.add(student)
db.session.commit()
# 创建空课程列表的学生
student = Student(
name="xiaohong",
age=14,
sex=False,
money=30000,
email="300000@qq.com",
)
db.session.add(student)
db.session.commit()
# 为现有学生添加课程(混合现有课程和新课程)
student = Student.query.filter(Student.name=="xiaohong").first()
student.course_list.append(Course.query.get(3)) # 添加已有课程
student.course_list.append(Course(name="python顶级", price=399.99)) # 创建新课程
db.session.commit()
# 批量扩展学生课程列表
student1 = Student.query.get(1)
course_list = Course.query.filter(Course.id.in_([1,2])).all()
student1.course_list.extend(course_list)
db.session.commit()
student2 = Student.query.get(2)
course_list = Course.query.filter(Course.id.in_([3,2])).all()
student2.course_list.extend(course_list)
db.session.commit()
return "ok"
# 数据查询路由
@app.route("/q1")
def q1():
"""查询学生课程和课程学生的关联数据"""
# 查询学生2的课程列表
student = Student.query.get(2)
course_list = [{"name":item.name,"price":float(item.price)} for item in student.course_list]
print("学生2的课程:", course_list)
# 查询课程2的学生列表
course = Course.query.get(2)
student_list = [{"name":item.name,"age":item.age} for item in course.student_list]
print("课程2的学生:", student_list)
return "ok"
# 数据更新路由
@app.route("/u1")
def u1():
"""更新选修课程3的学生钱包金额"""
course = Course.query.get(3)
for student in course.student_list:
student.money += 200
db.session.commit()
# 打印更新后的学生列表
print("更新后的学生列表:", course.student_list)
return "ok"
# 主程序入口
if __name__ == '__main__':
app.run()
1. 初始化Flask应用和SQLAlchemy对象
app = Flask(__name__, template_folder="templates", static_folder="static")
:初始化Flask应用,指定模板文件夹和静态文件夹。
db = SQLAlchemy()
:初始化SQLAlchemy对象,用于数据库操作。
db.init_app(app)
:将SQLAlchemy对象与Flask应用关联起来。
2. 配置数据库连接和其他设置
- 使用
app.config.update
方法配置Flask应用,包括开启调试模式、设置数据库URI、禁用SQLAlchemy对模型修改的跟踪以及开启SQLAlchemy的echo功能(用于打印生成的SQL语句)。
3. 定义数据库模型
定义了两个模型:
Student
(学生)和Course
(课程),以及它们之间的多对多关系表student_and_course
。
Student
模型包含学生的基本信息,如姓名、年龄、性别、邮箱和钱包余额。
Course
模型包含课程的基本信息,如课程名称和价格。使用
db.relationship
定义学生和课程之间的多对多关系,并通过secondary
参数指定关系表。
4. 数据库操作路由
/create
:创建数据库中所有模型对应的表。
/drop
:删除数据库中所有模型对应的表。
/a1
:添加学生和课程数据的示例,包括创建学生、为学生添加课程、查询学生并为其添加更多课程等。
/q1
:查询学生和课程数据的示例,展示如何查询某个学生的所有课程以及某个课程的所有学生。
/u1
:更新学生和课程数据的示例,展示如何为选修某门课程的所有学生增加钱包余额。
5. 辅助方法和属性
__repr__
方法:定义模型对象的字符串表示形式,便于调试。
__to_dict__
属性:使用@property装饰器定义,将模型对象转换为字典形式,便于JSON序列化。
6. 主程序入口
if __name__ == '__main__':
:当脚本作为主程序运行时,启动Flask应用。