flask框架一对多,多对多的关系

一对多关系

  • 多表关系中, 通过外键来关联数据
  • 一对多关系中, 外键设置在 多的一方

在这里插入图片描述

  • 通过关系属性来关系/查询数据 操作简单
    • 1> 需要定义外键
    • 2> 定义关系属性
    • 3> 使用关系属性来关联数据
# 用户表  一个用户有多个地址  一
class User(db.Model):
    __tablename__ = "users"  # 设置表名 表名默认为类名的小写
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(64), unique=True)
    # 创建关系属性  relationship("关联的类名", backref="对方表查询关联数据时的属性名")
    addresses = db.relationship("Address", backref="user")


# 地址表   多
class Address(db.Model):
    __tablename__ = "addresses"  # 设置表名 表名默认为类名的小写
    id = db.Column(db.Integer, primary_key=True)
    detail = db.Column(db.String(64), unique=True)
    # 设置外键(一般记录的是另一张表的主键)
    user_id = db.Column(db.Integer, db.ForeignKey("users.id"))


@app.route('/')
def index():
    # 删除 所有继承自db.Model的表
    db.drop_all()
    # 创建 所有的继承自db.Model的表
    db.create_all()
    """只通过外键来关联/查询数据 操作复杂"""
    # # 添加用户
    # user = User(name="zs")
    # db.session.add(user)
    # db.session.commit()  # 必须先提交, 否则没有生成主键, 设置外键无效
    #
    # # 添加地址
    # adr1 = Address(detail="中关村1号", user_id=user.id)
    # adr2 = Address(detail="陆家嘴1号", user_id=user.id)
    # db.session.add_all([adr1, adr2])
    # db.session.commit()
    #
    # # 查询数据  根据用户查询地址
    # adrs = Address.query.filter_by(user_id=user.id).all()
    # for adr in adrs:
    #     print(adr.detail)

    """通过关系属性来关系/查询数据 操作简单  1> 仍需要定义外键 2> 定义关系属性 3> 使用关系属性来关联数据"""
    user = User(name="zs")
    adr1 = Address(detail="中关村1号", user_id=user.id)
    adr2 = Address(detail="陆家嘴1号", user_id=user.id)
    # 关联数据
    # user.addresses = [adr1, adr2]
    user.addresses.append(adr1)
    user.addresses.append(adr2)
    # 添加到数据库中
    db.session.add_all([user, adr1, adr2])
    db.session.commit()
    # 使用关系属性来查询数据
    print(user.addresses)
    print(adr1.user)

    return 'index'

多对多关系

  • 多对多关系中, 必须创建独立的关系表来关联数据

在这里插入图片描述

  • 多对多中, 通过关系属性来关连/查询数据
    • 1> 定义关系表来设置外键
    • 2> 定义关系属性 多对多关系属性, 还需要设置参数secondary="关系表名"
    • 3> 使用关系属性来关联数据
from flask import Flask
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
# 设置数据库连接地址
app.config["SQLALCHEMY_DATABASE_URI"] = "mysql://root:mysql@127.0.0.1:3306/test18"
# 是否追踪数据库修改  很消耗性能, 不建议使用
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
# 设置在控制台显示底层执行的SQL语句
app.config["SQLALCHEMY_ECHO"] = False

# 创建数据库连接
db = SQLAlchemy(app)

# 创建关系表  多对多关系必须创建单独的表来记录关联数据
t_stu_cur = db.Table("table_stu_cur",
         db.Column("stu_id", db.Integer, db.ForeignKey("students.id"), primary_key=True),
         db.Column("cur_id", db.Integer, db.ForeignKey("courses.id"), primary_key=True)
         )


# 学生表  多  一个学生可以选多门课, 一门课也可以被多个学生选
class Student(db.Model):
    __tablename__ = "students"
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(64), unique=True)
    # 多对多关系属性, 还需要设置参数secondary="关系表名"
    courses = db.relationship("Course", backref="students", secondary="table_stu_cur")


# 课程表   多
class Course(db.Model):
    __tablename__ = "courses"
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(64), unique=True)



@app.route('/')
def index():
    # 删除 所有继承自db.Model的表
    db.drop_all()
    # 创建 所有的继承自db.Model的表
    db.create_all()
    """多对多 通过关系属性来关连/查询数据 操作简单  1> 定义关系表来设置外键 2> 定义关系属性 3> 使用关系属性来关联数据"""
    stu1 = Student(name="zs")
    stu2 = Student(name="ls")
    cur1 = Course(name="python")
    cur2 = Course(name="c")
    cur3 = Course(name="java")
    # 关联数据
    stu1.courses.append(cur1)
    stu1.courses.append(cur2)
    stu2.courses.append(cur2)
    stu2.courses.append(cur3)
    # 添加到数据库
    db.session.add_all([stu1, stu2, cur1, cur2, cur3])
    db.session.commit()

    print(stu1.courses)
    print(cur2.students)
    return 'index'


if __name__ == '__main__':
    app.run(debug=True)
附加:
  • 增删改处理 失败后还需要进行回滚 db.session.rollback()

  • 删除一对多的关联数据时, 先删多的一方, 再删除一的一方

  • 懒查询机制

# 默认一旦查询出数据, 就会该数据关联数据一起全查出来, 如果不想直接查询出所有的关联数据, 就可以使用懒查询机制
# 懒查询机制优点: 减少不必要的性能消耗, 按需获取
# 如果想要获取关联数据, 使用具体的all/first/count查询即可
# 懒查询机制只能用于对多关系 (1对多, 多对多)
courses = db.relationship("Course", backref=db.backref("students", lazy="dynamic"), secondary="table_stu_cur", lazy="dynamic")
  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值