python的flask框架对mysql数据库中数据表关联关系的处理 (二)many_to_many

本文介绍Flask-SQLAlchemy中实现多对多关系的方法,包括定义学生表和课程表,以及通过关联表sc来维护这两者之间的多对多关系。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

2018.05.18*******************************************************
author: wills

上篇blog介绍了flask-sqlalchemy数据库表格1对多关系的处理,这里介绍另一种关联关系
m –> n
多对多
many to many

假设有两张表,学生表Student,课程表Course
一个学生可以选择多门课程,一门课程可以被多个学生选择,所以这两个表格的关系是多对多

# models.py
class Student(db.Models)
    s_id = db.Column(db.Integer, primary_key=True, autoincrment=True)
    s_name = db.Column(db.String(16),)
    s_age = db.Column(db.Integer, default=10)
    # 外键 s_g关联到班级表,注意这里一定要先写字段s_g的类型integer
    # ‘grade.g_id’表示这个外键关联到Grade表的g_id字段
    s_g = db.Column(db.Integer,db.ForeignKey('grade.g_id'), nullable=True)

    __tablename__ = 'student'

    def __init__(self, name, age)
        # 初始化方法,方便创建学生对象
        self.s_name = name
        self.s_age = age

class Course(db.Model)

    c_id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    c_name = db.Column(db.String(16), unique=True)

    # students表示CourseStudent的关联关系,secondary=sc,表示他们的关联表
    # backref=’course‘表示学生查找班级时的办法
    studens = db.relationship('Student', secondary=sc, backref='course')

    __tablename__ = 'course'

        def __init__(self, name)
            self.c_name = name


# 为了方便处理两张表的多对多关系,引入了第三张表sc专门管理StudentCourse的关联关系
# sc这个表只有2个字段s_id与c_id(它们都是主键,并且又都是外键分别关联学生表和课程表),
# 分别关联到学生表s_id和课程表c_id,
sc = db.Table('sc', db.Column(db.Integer, db.ForeignKey('student.s_id'),primary_key=True),
                        db.Column(db.Integer, db.ForeignKey('course.c_id'), primary_key=True))


def create_db():
    """在数据库中创建对应的三个表
    """
    db.create_all()

    return 'ok'


# 表格创建完成,需要往其中添加相应的数据,我这里直接使用sql语句,Course表和Student表都没有问题,关键是
# 关联的sc表。假设Course表有5门课:1 -- math,2 -- physics,3 --history,4 -- chemistry,5 -- chinese
# 学生有三个id为1,2,3每人至少选了3门课,那么如何添加学生和课程的关系到sc表

def add_stu_cou():
    #添加 学生1的课程 课程id: 1, 2, 3
    # 首先拿到,对应学生对象和对应的三个课程对象
    stu = Student.query.get(1)
    cou1 = Course.query.get(1)
    cou2 = Course.query.get(2)
    cou3 = Course.query.get(3)

    # 然后将其添加到中间表sc。添加append  删除remove
    # 两表的关系是多对多,可以用学生对象找课程,也可以用课程找学生对象

    # 课程对象找学生对象
    cou1.students.append(stu)
    cou2.students.append(stu)
    # 学生对象找课程
    stu.course.append(cou3)
    cou = [cou1, cou2, stu]

    db.session.add_all(cou)
    db.session.commit()

    return '添加关联关系到sc表成功'


def delete_stu_course(s_id, c_id):
    """在中间表sc中删除学生与课程的关联关系
        s_id:学生的id
        c_id:学生对应课程的id
    """
    stu = Student.query.get(s_id)
    cou = Course.query.get(c_id)

    # 方法一 通过课程找学生删除
    cou.students.remove(stu)

    # 方法二 通过学生找课程删除
    stu.course.remove(cou)

    db.session.commit()

    return '删除成功'
Flask框架中,将MySQL数据转换为JSON并存储到`static`文件夹需要经过以下几个步骤: 1. **设置数据库连接**: 首先安装所需的库,如`flask_sqlalchemy`用于处理SQLAlchemyMySQL的集成,以及`flask_marshmallow`用于序列化数据到JSON格式。 ```bash pip install Flask-SQLAlchemy Flask-Marshmallow marshmallow-sqlalchemy ``` 2. **配置数据库**: 在`app.py`或其他配置模块中设置数据库连接,并创建模型(通常是基于SQLAlchemy的Model)。 ```python from flask_sqlalchemy import SQLAlchemy db = SQLAlchemy() # 创建一个User Model class User(db.Model): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(80), unique=True) email = db.Column(db.String(120), unique=True) # 序列化器 class UserSchema(ma.SQLAlchemyAutoSchema): class Meta: model = User ``` 3. **查询数据**: 获取用户列或其他需要序列化的数据。 ```python users = User.query.all() # 查询所有用户 ``` 4. **序列化数据到JSON**: 使用`marshmallow`库将数据转换为JSON。 ```python from flask_marshmallow import Marshmallow ma = Marshmallow(app) user_schema = UserSchema(many=True) # 处理批量数据 json_data = user_schema.dump(users) ``` 5. **保存到`static`文件夹**: 将JSON数据保存到应用的静态文件夹,通常这个过程会在模板渲染时完成。例如,你可以创建一个新的HTML页面,然后在视图函数中处理这个操作。 ```python @app.route('/export_json') def export_to_json(): with open(os.path.join('static', 'users.json'), 'w') as f: json.dump(json_data, f) return redirect(url_for('index')) # 返回主页,示数据已导出 ``` 6. **模板中引用**: 在前端模板(如Jinja2)中,你可以通过URL访问`users.json`获取数据,假设你有如下代码: ```html <a href="{{ url_for('export_to_json') }}">Download JSON</a> <script src="{{ url_for('static', filename='users.json') }}"></script> ``` 注意,这只是一个基本示例,实际生产环境中可能需要考虑错误处理、文件权限等问题。同时,直接在`static`目录下写入文件可能会导致安全性问题,因此最好使用更为安全的方式,比如写入到服务器指定的临时目录,然后通过URL分发。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

披星の月

您的鼓励是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值