flask的orm框架SQLAlchemy查詢實現(xiàn)解析
這篇文章主要介紹了flask的orm框架SQLAlchemy查詢實現(xiàn)解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
一對多,多對多是什么?
一對多。例如,班級與學生,一個班級對應多個學生,或者多個學生對應一個班級。
多對多。例如,學生與課程,可以有多個學生修同一門課,同時,一門課也有很多學生。
一對多查詢
如果一個項目,有兩張表。分別是班級表,學生表。
在設(shè)計數(shù)據(jù)表時,我們給學生表設(shè)置一個外鍵,指向班級表的 id 。
sqlalchemy 模板創(chuàng)建表的代碼:
from flask import Flask, render_template, request, flash, redirect from flask_sqlalchemy import SQLAlchemy app = Flask(__name__,static_folder="static",template_folder="templates") # 設(shè)置數(shù)據(jù)庫連接屬性 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")) # 注意要寫成(表名.字段名)
創(chuàng)建完表,插入完數(shù)據(jù)后。
如果我們知道學生的學號,要查學生班級的名稱,應該怎么操作呢?
現(xiàn)在可以用一種比較麻煩的方達查詢:
cls_id = Students.query.filter(Student.id == 'xxx').first() cls = Classes.query.filter(Classes.id == cls.id).first() print(cls.name)
這樣的方法太麻煩了,有沒有簡單的辦法?
上面創(chuàng)建表的代碼,在18行可以插入一條語句。
relate_student = db.relationship("Students",backref='relate_class',lazy='dynamic')
其中realtionship描述了Students和Classes的關(guān)系。在此文中,第一個參數(shù)為對應參照的類"Students"
第二個參數(shù)backref為類Students申明新屬性的方法
第三個參數(shù)lazy決定了什么時候SQLALchemy從數(shù)據(jù)庫中加載數(shù)據(jù)
如果設(shè)置為子查詢方式(subquery),則會在加載完Classes對象后,就立即加載與其關(guān)聯(lián)的對象,這樣會讓總查詢數(shù)量減少,但如果返回的條目數(shù)量很多,就會比較慢
另外,也可以設(shè)置為動態(tài)方式(dynamic),這樣關(guān)聯(lián)對象會在被使用的時候再進行加載,并且在返回前進行過濾,如果返回的對象數(shù)很多,或者未來會變得很多,那最好采用這種方式
如果一大堆理論看不明白,那么知道怎么用就可以了。
如果知道學生的姓名,想知道班級的名稱,可以這樣查:
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 表
可以使用這樣的方法,有兩個要求,第一是要設(shè)置外鍵,第二是這句語句:
relate_student = db.relationship("Students",backref='relate_class',lazy='dynamic')
注意,什么時候用 relate_student ,什么時候用 relate_class 。以及 relationship 這條語句的書寫,要清楚!
多對多查詢
假設(shè)一堆學生選了不同的課程,這就是多對多關(guān)系。
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) # 關(guān)聯(lián)屬性,多對多的情況,可以寫在任意一個模型類中 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)
添加測試數(shù)據(jù):
# 添加測試數(shù)據(jù) stu1 = Student(name='張三') stu2 = Student(name='李四') stu3 = Student(name='王五') cou1 = Course(name='物理') cou2 = Course(name='化學') cou3 = Course(name='生物') stu1.courses = [cou2, cou3] # 記得要添加關(guān)系 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)
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
python matplotlib.pyplot.plot()參數(shù)用法
這篇文章主要介紹了python matplotlib.pyplot.plot()參數(shù)用法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-04-04python從list列表中選出一個數(shù)和其對應的坐標方法
今天小編就為大家分享一篇python從list列表中選出一個數(shù)和其對應的坐標方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-07-07Python 實現(xiàn)繪制子圖及子圖刻度的變換等問題
這篇文章主要介紹了Python 實現(xiàn)繪制子圖及子圖刻度的變換等問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-05-05對numpy中二進制格式的數(shù)據(jù)存儲與讀取方法詳解
今天小編就為大家分享一篇對numpy中二進制格式的數(shù)據(jù)存儲與讀取方法詳解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-11-11