一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

flask的orm框架(SQLAlchemy)

 花心的程序員 2021-01-27
  • 一對多,多對多是什么?

一對多。例如,班級與學(xué)生,一個(gè)班級對應(yīng)多個(gè)學(xué)生,或者多個(gè)學(xué)生對應(yīng)一個(gè)班級。

多對多。例如,學(xué)生與課程,可以有多個(gè)學(xué)生修同一門課,同時(shí),一門課也有很多學(xué)生。

  • 一對多查詢

如果一個(gè)項(xiàng)目,有兩張表。分別是班級表,學(xué)生表。

在設(shè)計(jì)數(shù)據(jù)表時(shí),我們給學(xué)生表設(shè)置一個(gè)外鍵,指向班級表的 id 。

sqlalchemy 模板創(chuàng)建表的代碼:

 

復(fù)制代碼
 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 # 設(shè)置數(shù)據(jù)庫連接屬性
 7 app.config['SQLALCHEMY_DATABASE_URI'] = '×××'
 8 app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
 9 
10 # 實(shí)例化 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 # 學(xué)生表
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"))    # 注意要寫成(表名.字段名)
復(fù)制代碼

創(chuàng)建完表,插入完數(shù)據(jù)后。

如果我們知道學(xué)生的學(xué)號,要查學(xué)生班級的名稱,應(yīng)該怎么操作呢?

現(xiàn)在可以用一種比較麻煩的方達(dá)查詢:

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)系。在此文中,第一個(gè)參數(shù)為對應(yīng)參照的類"Students"
  • 第二個(gè)參數(shù)backref為類Students申明新屬性的方法
  • 第三個(gè)參數(shù)lazy決定了什么時(shí)候SQLALchemy從數(shù)據(jù)庫中加載數(shù)據(jù)
    • 如果設(shè)置為子查詢方式(subquery),則會在加載完Classes對象后,就立即加載與其關(guān)聯(lián)的對象,這樣會讓總查詢數(shù)量減少,但如果返回的條目數(shù)量很多,就會比較慢
    • 另外,也可以設(shè)置為動(dòng)態(tài)方式(dynamic),這樣關(guān)聯(lián)對象會在被使用的時(shí)候再進(jìn)行加載,并且在返回前進(jìn)行過濾,如果返回的對象數(shù)很多,或者未來會變得很多,那最好采用這種方式

如果一大堆理論看不明白,那么知道怎么用就可以了。

如果知道學(xué)生的姓名,想知道班級的名稱,可以這樣查:

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

如果知道班級的名稱,想返回全部學(xué)生的名字的列表,可以這樣查:

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

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

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

注意,什么時(shí)候用 relate_student ,什么時(shí)候用 relate_class 。以及 relationship 這條語句的書寫,要清楚!

 

  • 多對多查詢

假設(shè)一堆學(xué)生選了不同的課程,這就是多對多關(guān)系。

復(fù)制代碼
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)屬性,多對多的情況,可以寫在任意一個(gè)模型類中 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)
復(fù)制代碼

添加測試數(shù)據(jù):

復(fù)制代碼
# 添加測試數(shù)據(jù)

    stu1 = Student(name='張三')
    stu2 = Student(name='李四')
    stu3 = Student(name='王五')

    cou1 = Course(name='物理')
    cou2 = Course(name='化學(xué)')
    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()
復(fù)制代碼

要查某個(gè)學(xué)生修的全部課程,修了某個(gè)課程的全部學(xué)生:

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

for student in cou2.relate_student:
    print(student)

 

    本站是提供個(gè)人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    东京热一二三区在线免| 日本人妻熟女一区二区三区| 欧美精品一区二区三区白虎| 中文字幕不卡欧美在线| 日韩一级毛一欧美一级乱| 国产成人综合亚洲欧美日韩| 国产中文另类天堂二区| 伊人国产精选免费观看在线视频| 精品久久综合日本欧美| 色哟哟哟在线观看视频| 欧美一二三区高清不卡| 国产精品香蕉在线的人| 色婷婷视频国产一区视频| 久久女同精品一区二区| 国产日韩欧美一区二区| 欧美日韩国产另类一区二区| 亚洲中文字幕综合网在线| 欧美黑人巨大一区二区三区| 91熟女大屁股偷偷对白| 日韩熟妇人妻一区二区三区| 偷拍美女洗澡免费视频| 美日韩一区二区精品系列| 欧美人妻一区二区三区| 性欧美唯美尤物另类视频| 婷婷基地五月激情五月| 国产高清视频一区不卡| 少妇人妻无一区二区三区| 日本少妇三级三级三级| 欧美色欧美亚洲日在线| 国产午夜福利一区二区| 在线懂色一区二区三区精品| 国产精品第一香蕉视频| 精品人妻一区二区三区四在线| 欧美日韩国产自拍亚洲| 久久精品一区二区少妇| 久久99热成人网不卡| 日本加勒比在线观看一区| 欧洲自拍偷拍一区二区| 黑人粗大一区二区三区| 欧美日韩国产午夜福利| av在线免费观看在线免费观看|