07-多对多操作

时间:2019-10-18 21:03:24   收藏:0   阅读:47

多对多演练

  在项目开发过程中,会遇到很多数据之间的多对多关系的情况,比如:

 1、学生和课程

 2、老师和班级

等等都是多对多的关系,所以在开发过程中需要使用ORM模型将表与表的多对多关联关系使用代码描述出来。多对多关系描述有一个唯一的点就是:需要添加一张单独的表去记录两张表之间的对应关系。

场景示例:

需求分析:

  1、学生可以网上选课,学生有多个,课程也有多个。

  需求:查询某个学生选修了那些课程

     查询某个课程都有那些学生选择

分析表格如下:

学生表(Student):

主键(id)学生名(name)
1 张三
2 李四
3 老王

选修课(Course):

主键(id)课程名(name)
1 物理
2 化学
3 生物

数据关联表(Student_Course):

主键(student.id)主键(course.id)
1 2
1 3
2 2
3 1
3 2
3 3

定义模型以及表:

 

技术分享图片
#导入flask类,
from flask import Flask
#5、导入类 实例化对象
from flask_sqlalchemy import SQLAlchemy

#1、实例化flask类,并传入本地包
app = Flask(__name__)

#2、设置密钥
app.config["SECRET_KEY"] = "SECRET_KEY"
#3、链接数据库
app.config["SQLALCHEMY_DATABASE_URI"] = "mysql://root:@127.0.0.1:3306/flasksql"
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = True
#4、查询时显示原SQL语句
app.config["SQLALCHEMY_ECHO"] = True
#5、实例化SQLAlchemy对象db,对那个app操作
db = SQLAlchemy(app)
#7、多对多需要第三张表,第三张表如图所示,第一个参数表名,第二个参数列>>>>
tb_student_course = db.Table("tb_student_course",
                    db.Column("student_id",db.Integer,db.ForeignKey("students.id")),
                    db.Column("course_id",db.Integer,db.ForeignKey("courses.id"))
                             )


#6、开始定义模型类  对表操作
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",secondary=tb_student_course,backref="student",
                              lazy="dynamic")

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

if __name__ == __main__:
    db.drop_all()
    db.create_all()

    #添加测试数据
    stu1 = Student(name=张三)
    stu2 = Student(name=李四)
    stu3 = Student(name=老王)

    cou1 = Course(name=物理)
    cou2 = Course(name=化学)
    cou3 = Course(name=生物)

    stu1.courses = [cou2, cou3]
    stu2.courses = [cou2]
    stu3.courses = [cou1, cou2, cou3]

    db.session.add_all([stu1, stu2, stu2])
    db.session.add_all([cou1, cou2, cou3])

    db.session.commit()

    app.run(debug=True)
多对多

数据库迁移

1、首先要在虚拟环境中安装Flask-Migrate:

 

pip3 install flask-migrate

 

2、代码文件

from flask import Flask

from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate,MigrateCommand
from flask_script import Shell,Manager

app = Flask(__name__)
manager = Manager(app)
#我的密码没有。所以root后面没有
app.config[SQLALCHEMY_DATABASE_URI] = mysql://root:@127.0.0.1:3306/Flask_test
app.config[SQLALCHEMY_COMMIT_ON_TEARDOWN] = True
app.config[SQLALCHEMY_TRACK_MODIFICATIONS] = True
db = SQLAlchemy(app)

#第一个参数是Flask的实例,第二个参数是Sqlalchemy数据库实例
migrate = Migrate(app,db) 

#manager是Flask-Script的实例,这条语句在flask-Script中添加一个db命令
manager.add_command(db,MigrateCommand)

#定义模型Role
class Role(db.Model):
    # 定义表名
    __tablename__ = roles
    # 定义列对象
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(64), unique=True)
    user = db.relationship(User, backref=role)

    #repr()方法显示一个可读字符串,
    def __repr__(self):
        return Role:.format(self.name)

#定义用户
class User(db.Model):
    __talbe__ = users
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(64), unique=True, index=True)
    #设置外键
    role_id = db.Column(db.Integer, db.ForeignKey(roles.id))

    def __repr__(self):
        return User:.format(self.username)


if __name__ == __main__:
    manager.run()

创建迁移仓库

 

#这个命令会创建migrations文件夹,所有迁移文件都放在里面。
python database.py db init

创建迁移脚本

python database.py db migrate -m initial migration

更新数据库

python database.py db upgrade

返回以前版本

可以根据history命令找到版本号,然后传给downgrade命令:

python app.py db history

输出格式:
<base> -> 版本号 (head), initial migration

回滚到指定版本:

python app.py db downgrade 版本号

实际操作顺序:

常见关系模块

一对多

技术分享图片
class Role(db.Model):
    """角色表"""
    __tablename__ = roles

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(64), unique=True)
    users = db.relationship(User, backref=role, lazy=dynamic)

class User(db.Model):
    """用户表"""
    __tablename__ = users
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(64), unique=True, index=True)
一对多

多对多

技术分享图片
tb_student_course = db.Table(tb_student_course,
                             db.Column(student_id, db.Integer, db.ForeignKey(students.id)),
                             db.Column(course_id, db.Integer, db.ForeignKey(courses.id))
                             )

class Student(db.Model):
    __tablename__ = "students"
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(64), unique=True)

    courses = db.relationship(Course, secondary=tb_student_course,
                              backref=db.backref(students, lazy=dynamic),
                              lazy=dynamic)

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

自关联一对多(了解):

技术分享图片
class Comment(db.Model):
    """评论"""
    __tablename__ = "comments"

    id = db.Column(db.Integer, primary_key=True)
    # 评论内容
    content = db.Column(db.Text, nullable=False)
    # 父评论id
    parent_id = db.Column(db.Integer, db.ForeignKey("comments.id"))
    # 父评论(也是评论模型)
    parent = db.relationship("Comment", remote_side=[id],
                             backref=db.backref(childs, lazy=dynamic))

# 测试代码
if __name__ == __main__:
    db.drop_all()
    db.create_all()

    com1 = Comment(content=我是主评论1)
    com2 = Comment(content=我是主评论2)
    com11 = Comment(content=我是回复主评论1的子评论1)
    com11.parent = com1
    com12 = Comment(content=我是回复主评论1的子评论2)
    com12.parent = com1

    db.session.add_all([com1, com2, com11, com12])
    db.session.commit()
    app.run(debug=True)
View Code

自关联多对多(了解):

技术分享图片
tb_user_follows = db.Table(
    "tb_user_follows",
    db.Column(follower_id, db.Integer, db.ForeignKey(info_user.id), primary_key=True),  # 粉丝id
    db.Column(followed_id, db.Integer, db.ForeignKey(info_user.id), primary_key=True)  # 被关注人的id
)

class User(db.Model):
    """用户表"""
    __tablename__ = "info_user"

    id = db.Column(db.Integer, primary_key=True)  
    name = db.Column(db.String(32), unique=True, nullable=False)

    # 用户所有的粉丝,添加了反向引用followed,代表用户都关注了哪些人
    followers = db.relationship(User,
                                secondary=tb_user_follows,
                                primaryjoin=id == tb_user_follows.c.followed_id,
                                secondaryjoin=id == tb_user_follows.c.follower_id,
                                backref=db.backref(followed, lazy=dynamic),
                                lazy=dynamic)
View Code

 

原文:https://www.cnblogs.com/lishuntao/p/11700161.html

评论(0
© 2014 bubuko.com 版权所有 - 联系我们:wmxa8@hotmail.com
打开技术之扣,分享程序人生!