flask连接mysql数据库的一对一,一对多,多对多的处理关系。

本文详细介绍了一对一、一对多及多对多关系在Flask应用中的实现方法,包括模型定义、数据操作及关系查询,适用于理解Flask与数据库交互的初学者。

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

Y18


   以学生表与班级表为例,进行一对一,与一对多操作说明。

简单部署:

1、创建flask文件夹,在文件夹中创建python文件,命名为app,其中代码:

from flask import Flask
app = Flask(__name__)

2、引入封装过的连接mysql数据库的操作文件,db_operate.py(Y17已介绍)

3、创建__init__文件为启动文件。代码为:

from  flask.app import app
if __name__ == '__main__':
    app.run(debug=False)

一、一对一,假设学生与班级的关系是一对一,以下:

1、创建一对一模型文件models_oto.py,相关代码以及操作如下:

# 引入操作封装文件中的类方法和db数据库
from flask.db_operate import DBO,db
# 创建班级模型
class Grade(db.Model, DBO):
    g_id = db.Column(db.Integer, primary_key=True)
    g_name = db.Column(db.String(30), nullable=False, unique=True)
    g_num = db.Column(db.Integer, default=0)
    # 一对一关系写法
    stus = db.relationship('Student', backref='gd', uselist=False)
    __tablename__ = 'grade'
    def __init__(self, **kwargs):
        for key, value in kwargs.items():
            setattr(self, key, value)
            
# 创建学生模型
class Student(db.Model, DBO):
    s_id = db.Column(db.Integer, primary_key=True)
    s_name = db.Column(db.String(30), nullable=False)
    s_age = db.Column(db.Integer)
    s_sex = db.Column(db.String(10), nullable=False)
    s_gid = db.Column(db.Integer, db.ForeignKey('grade.g_id'))
    __tablename__ = 'stu'
    def __init__(self, **kwargs):
        for key, value in kwargs.items():
            setattr(self, key, value)

# 创建account对象
db.create_all()
stu1 = Student(s_id=101, s_name='y1', s_sex='男' , s_age=25)
stu2 = Student(s_id=108, s_name='y2', s_sex='女' , s_age=27)
stu3 = Student(s_id=110, s_name='y3', s_sex='男' , s_age=30)

# 正常添加
# grade1 = Grade(g_id=1, g_name='py1', g_num=10)
# grade1.stus = stu1
# db.session.add(grade1)
# db.session.commit()

# 封装添加
# grade1 = Grade.add(g_id=2, g_name='py2', g_num=27,stus = stu2)

# 修改学生信息
# 1. 无联系修改
# students = Student.query.get(100).update(s_age=77)
# 2. 通过联系修改
# grade1 = Grade.query.get(2)
# students = grade1.stus.update(s_age=29)
# grade1.update(g_num=100)

# 删除
# grade1 = Grade.query.get(1)
# studs = grade1.stus.delete()
# grade1.delete()

# 通过子表访问主表
# stu = Student.query.get(108)
# print(stu.gd.g_name)

2、在__init__中导入模型文件,如下。注释部分,测试哪段解封哪段即可,之后运行__init__文件,根据所需测试。

import flask.models_oto

二、一对多,学生与班级的关系是多对一,以下:

1、创建一对多模型文件models_otm.py,相关代码以及操作如下:

from flask.db_operate import DBO,db
class Grade(db.Model, DBO):
    g_id = db.Column(db.Integer, primary_key=True)
    g_name = db.Column(db.String(30), nullable=False, unique=True)
    g_num = db.Column(db.Integer, default=0)
    # relationship():在主表中提前声明存在关系的两个类,backref设置的是子表操作主表数据时依据的字段,stus:代表主表操作子表中数据时依据的字段。lazy:设置当前数据的加载方式为懒加载
    # 一对多写法
    stus = db.relationship('Student', backref='gd', lazy='dynamic')
    __tablename__ = 'grade'
    def __init__(self, **kwargs):
        # self.g_id = kwargs.get('g_id')
        for key, value in kwargs.items():
            setattr(self, key, value)

class Student(db.Model, DBO):
    s_id = db.Column(db.Integer, primary_key=True)
    s_name = db.Column(db.String(30), nullable=False)
    s_age = db.Column(db.Integer)
    s_sex = db.Column(db.String(10), nullable=False)
    s_gid = db.Column(db.Integer, db.ForeignKey('grade.g_id'))
    __tablename__ = 'stu'
    def __init__(self, **kwargs):
        for key, value in kwargs.items():
            setattr(self, key, value)

# 创建account对象
db.create_all()
stu1 = Student(s_id=107, s_name='y1', s_sex='男' , s_age=25)
stu2 = Student(s_id=108, s_name='y2', s_sex='女' , s_age=27)
stu3 = Student(s_id=109, s_name='y3', s_sex='男' , s_age=30)

# 正常添加
# grade1 = Grade(g_id=1, g_name='py1', g_num=17)
# grade1.stus = [stu1,stu2,stu3]
# db.session.add(grade1)
# db.session.commit()

# 封装添加
# grade1 = Grade.add(g_id=2, g_name='py3', g_num=27,stus = [stu1,stu2,stu3])

# 相同班级添加学生(更新数据)
# grade1 = Grade.query.get(1)
# students = grade1.stus.all()
# for stu in [stu1,stu2,stu3]:
#     students.append(stu)
# grade1.update(stus = students, g_num=6)

# 删除
# grade1 = Grade.query.get(2)
# studs = grade1.stus.all()
# for stu in studs:
#     stu.delete()
# grade1.delete()

# 通过子表访问主表
# stu = Student.query.get(104)
# print(stu.gd.g_name)

2、在__init__中导入模型文件,如下。注释部分,测试哪段解封哪段即可,之后运行__init__文件,根据所需测试。

import flask.models_otm

三、多对多,学生与课程的关系是多对多,以下:

1、flask中,多对多关系的创建必须通过一个中间表连接两个表(中间表只有两列且都为外键,外键分别为连接两个表中的主键。中间表不进行任何操作,仅提供联系用途),创建多对多模型文件models_mtm.py,相关代码以及操作如下:

from flask5.db_operate import db, DBO

# 创建多对多关系的中间表
sm_relation = db.Table(
    'sm_relation',       # 表格名称
    db.Column('ss_id', db.Integer, db.ForeignKey('student.s_id')),  # 第一列数据设置
    db.Column('mm_id', db.Integer, db.ForeignKey('major.m_id'))
)

# 创建学生模型
class Student(db.Model, DBO):
    __tablename__ ='student'
    s_id = db.Column(db.Integer, primary_key=True)
    s_name = db.Column(db.String(77), nullable=False)
    s_age = db.Column(db.Integer, nullable=False)
    s_sex = db.Column(db.String(7), nullable=False)
    majors = db.relationship('Major',  backref='stus', lazy='dynamic',secondary=sm_relation)  #secondary用来设置多对多关系中的第三个表格对象

# 创建课程模型
class Major(db.Model, DBO):
    __tablename__ ='major'
    m_id = db.Column(db.Integer, primary_key=True)
    m_name = db.Column(db.String(77), nullable=False)
    m_score = db.Column(db.Float,nullable=False)

# 创建表格对象
db.create_all()

# 添加若干科目信息
# Major.add([
#     {'m_id':1, 'm_name':'高等数学', 'm_score':5},
#     {'m_id':2, 'm_name':'概率论', 'm_score':3},
#     {'m_id':3, 'm_name':'大学英语', 'm_score':3},
#     {'m_id':4, 'm_name':'马克思主义', 'm_score':7},
#     {'m_id':5, 'm_name':'数据结构', 'm_score':6},
# ])

# 定义学生对象,模拟选课操作
# Student.add([
#     {'s_id':100, 's_name':'小一', 's_age':7, 's_sex':'男'},
#     {'s_id':101, 's_name':'小二', 's_age':17, 's_sex':'男'},
#     {'s_id':102, 's_name':'小三', 's_age':27, 's_sex':'女'},
# ])

# # 模拟选课(添加多对多数据往在第三个中间表中)
# majors = ['高等数学','概率论','大学英语']
# # 查询对应课程的对象
# major_list = []
# for name in majors:
#     major = Major.query.filter(Major.m_name == name).first()
#     major_list.append(major)
# # 将X学生选择的课程绑定给X学生
# Student.query.get(101).update(majors=major_list)

# 根据学生查询对应的科目
# stu = Student.query.get(100)
# stu_m = stu.majors.all()
# # print(stu_m)
# for s_major in stu_m:
#     print(s_major.m_name)

# 根据科目查询对应的学生
# major = Major.query.get(1)
# major_s = major.stus
# # print(major_s)
# for m_stus in major_s:
#     print(m_stus.s_name)

2、在__init__中导入模型文件,如下。注释部分,测试哪段解封哪段即可,之后运行__init__文件,根据所需测试。

import flask.models_mtm

源代码链接:(flask4为一对一,一对多。 flask5为多对多)
https://pan.baidu.com/s/10_vZeB9cB-ZiftsVhie3NQ  提取码:33nq


个人小结,定有不足,欢迎指点。
谢谢~

### Flask 连接 MySQL 数据库并删除数据 要实现 Flask 应用程序连接MySQL 并执行删除操作,可以通过 Python 的 `pymysql` 或者 `mysql-connector-python` 驱动来完成。以下是完整的流程以及代码示例。 #### 安装依赖项 首先需要安装必要的包: ```bash pip install flask pymysql ``` #### 创建 Flask 应用并与 MySQL 连接 下面是一个简单的 Flask 应用程序,它展示了如何连接MySQL 数据库并执行删除操作: ```python from flask import Flask, request, jsonify import pymysql.cursors app = Flask(__name__) # 数据库配置 db_config = { 'host': 'localhost', 'user': 'root', # 替换为实际用户名 'password': '', # 替换为实际密码 'database': 'test_db' # 替换为实际数据库名 } @app.route('/delete/<int:id>', methods=['DELETE']) def delete_data(id): try: connection = pymysql.connect(**db_config) with connection.cursor() as cursor: sql_query = "DELETE FROM users WHERE id=%s" cursor.execute(sql_query, (id,)) if cursor.rowcount > 0: response = {'message': f'Record {id} deleted successfully'} else: response = {'error': f'Record {id} not found'}, 404 connection.commit() except Exception as e: response = {'error': str(e)}, 500 finally: connection.close() return jsonify(response) if __name__ == '__main__': app.run(debug=True) ``` 上述代码实现了以下功能: 1. 使用 `pymysql` 来建立与 MySQL 数据库连接[^1]。 2. 提供了一个 `/delete/<id>` 路由,用于接收 DELETE 请求,并根据传入的 ID 删除对应记录。 3. 如果删除成功,则返回成功消息;如果没有找到对应的记录,则返回错误提示和状态码 404;如果发生异常,则捕获并返回错误信息及状态码 500。 #### 注意事项 - **安全性**:在生产环境中,应避免硬编码敏感信息(如用户名、密码),建议使用环境变量或其他安全方式存储这些信息。 - **事务管理**:对于涉及个表的操作,需考虑启用事务支持以确保一致性。 - **SQL 注入防护**:始终使用参数化查询而非字符串拼接构建 SQL 查询语句,防止潜在的安全风险[^2]。 #### Kafka Connect 同步至 MySQL 的扩展思考 虽然本问题是关于 FlaskMySQL 的交互,但如果涉及到更复杂的场景(例如实时同步 Kafka 中的数据到 MySQL),可以参考 Kafka Connect 工具的相关文档[^3]。这可能适用于某些分布式系统的架构设计需求。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值