flask的orm框架(SQLAlchemy)-一對多查詢以及多對多查詢

  • 一對多,多對可能是什麼?

一對多。例如,班級與學生,一個班級對應多個學生,或者多個學生對應一個班級。sql

多對多。例如,學生與課程,能夠有多個學生修同一門課,同時,一門課也有不少學生。數據庫

  • 一對多查詢

若是一個項目,有兩張表。分別是班級表,學生表。flask

在設計數據表時,咱們給學生表設置一個外鍵,指向班級表的 id 。session

sqlalchemy 模板建立表的代碼:app

 

 1 from flask import Flask, render_template, request, flash, redirect
 2 from flask_sqlalchemy import SQLAlchemy
 3 
 4 app = Flask(__name__,static_folder="static",template_folder="templates")
 5 
 6 # 設置數據庫鏈接屬性
 7 app.config['SQLALCHEMY_DATABASE_URI'] = '×××'
 8 app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
 9 
10 # 實例化 ORM 操做對象
11 db = SQLAlchemy(app)
12 
13 # 班級表
14 class Classes(db.Model):
15     __tablename__ = "classes"
16     id = db.Column(db.Integer,primary_key=True)
17     name = db.Column(db.String(20),nullable=False,unique=True)
18 
19 # 學生表
20 class Students(db.Model):
21     __tablename__ = "students"
22     id = db.Column(db.Integer,primary_key=True)
23     name = db.Column(db.String(40),nullable=False)
24     cls_id = db.Column(db.Integer,db.ForeignKey("classes.id"))    # 注意要寫成(表名.字段名)

建立完表,插入完數據後。測試

若是咱們知道學生的學號,要查學生班級的名稱,應該怎麼操做呢?spa

如今能夠用一種比較麻煩的方達查詢:設計

cls_id = Students.query.filter(Student.id == 'xxx').first()
cls = Classes.query.filter(Classes.id == cls.id).first()
print(cls.name)

這樣的方法太麻煩了,有沒有簡單的辦法?code

上面建立表的代碼,在18行能夠插入一條語句。orm

relate_student = db.relationship("Students",backref='relate_class',lazy='dynamic')
  • 其中realtionship描述了Students和Classes的關係。在此文中,第一個參數爲對應參照的類"Students"
  • 第二個參數backref爲類Students申明新屬性的方法
  • 第三個參數lazy決定了何時SQLALchemy從數據庫中加載數據
    • 若是設置爲子查詢方式(subquery),則會在加載完Classes對象後,就當即加載與其關聯的對象,這樣會讓總查詢數量減小,但若是返回的條目數量不少,就會比較慢
    • 另外,也能夠設置爲動態方式(dynamic),這樣關聯對象會在被使用的時候再進行加載,而且在返回前進行過濾,若是返回的對象數不少,或者將來會變得不少,那最好採用這種方式

若是一大堆理論看不明白,那麼知道怎麼用就能夠了。

若是知道學生的姓名,想知道班級的名稱,能夠這樣查:

stu = Students.query.filter(Students.name == 'xxx').first()
stu.relate_class.name    # stu.relate_class 會跳到 classes 表

若是知道班級的名稱,想返回所有學生的名字的列表,能夠這樣查:

cls = Classes.query.filter(Classes.name == 'xxx').first()
cls.relate_student.name    # cls.relate_stu 會跳到 students 表

可使用這樣的方法,有兩個要求,第一是要設置外鍵,第二是這句語句:

relate_student = db.relationship("Students",backref='relate_class',lazy='dynamic')

注意,何時用 relate_student ,何時用 relate_class 。以及 relationship 這條語句的書寫,要清楚!

 

  • 多對多查詢

假設一堆學生選了不一樣的課程,這就是多對多關係。

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)

   # 關聯屬性,多對多的狀況,能夠寫在任意一個模型類中 relate_courses
= db.relationship('Course', secondary=tb_student_course, backref='relate_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)

添加測試數據:

# 添加測試數據

    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()

要查某個學生修的所有課程,修了某個課程的所有學生:

for course in stu1.relate_courses:
    print(course.name)

for student in cou2.relate_student:
    print(student)
相關文章
相關標籤/搜索