1. 程式人生 > 程式設計 >flask的orm框架SQLAlchemy查詢實現解析

flask的orm框架SQLAlchemy查詢實現解析

這篇文章主要介紹了flask的orm框架SQLAlchemy查詢實現解析,文中通過示例程式碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下

一對多,多對多是什麼?

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

多對多。例如,學生與課程,可以有多個學生修同一門課,同時,一門課也有很多學生。

一對多查詢

如果一個專案,有兩張表。分別是班級表,學生表。

在設計資料表時,我們給學生表設定一個外來鍵,指向班級表的 id 。

sqlalchemy 模板建立表的程式碼:

from flask import Flask,render_template,request,flash,redirect
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__,static_folder="static",template_folder="templates")

# 設定資料庫連線屬性
app.config['SQLALCHEMY_DATABASE_URI'] = '×××'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

# 例項化 ORM 操作物件
db = SQLAlchemy(app)

# 班級表
class Classes(db.Model):
  __tablename__ = "classes"
  id = db.Column(db.Integer,primary_key=True)
  name = db.Column(db.String(20),nullable=False,unique=True)

# 學生表
class Students(db.Model):
  __tablename__ = "students"
  id = db.Column(db.Integer,primary_key=True)
  name = db.Column(db.String(40),nullable=False)
  cls_id = db.Column(db.Integer,db.ForeignKey("classes.id"))  # 注意要寫成(表名.欄位名)

建立完表,插入完資料後。

如果我們知道學生的學號,要查學生班級的名稱,應該怎麼操作呢?

現在可以用一種比較麻煩的方達查詢:

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

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

上面建立表的程式碼,在18行可以插入一條語句。

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",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.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,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,cou3])

  db.session.commit()

要查某個學生修的全部課程,修了某個課程的全部學生:

for course in stu1.relate_courses:
  print(course.name)
for student in cou2.relate_student:
  print(student)

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。