flask 中的ORM


1 響應(response)
    1 什么是響應
        響應就是由服務器端帶給客戶端的內容,對應着請求,響應可以是普通的字符串,模板 或重定向
        return '普通字符串'
        return render_template('xxx.html')
    2 響應對象
        響應對象:將響應的內容封裝到一個對象中,可以完成更多的響應的行為(如:增加cookies,..)
        在Flask中,使用 make_response() 構建響應對象

      request.cookies['uname']   #'獲取cooki'
2 文件上傳 1 注意問題 表單中如果有文件上傳的話,必須遵循以下兩個要求 1 提交方式 method 必須為 post 2 表單的 enctype 屬性值必須為 multipart/form-data 2 服務器端 1 通過 request.files 獲取文件上傳 f = request.files['文件框的name值'] 2 通過 f.save(保存路徑) 將文件保存至指定目錄處 通過 f.filename 獲取文件的名稱 f.save('/static')#文件路徑 3 模型 - Models 1 什么是模型 模型,是根據數據庫中表的結構而創建出來的class 表中的每一個列對應到編程語言中就class中的一個屬性 2 模型的框架- orm 1 數據表(table)到編程類(class)的映射 數據庫中的每一張表 對應到 編程語言中 都有一個類 在ORM中: 允許將數據表 自動生成一個類 允許將類自動 生成一張數據表 2 數據類型的映射 將數據庫表中的字段以及數據類型 對應到 編程語言中類的屬性 在ORM中: 允許將表中的字段和數據類型自動映射到編程語言中 也允許將類中的屬性和數據類型也自動映射到表中 3 關系映射 將數據庫中表與表之間的關系 對應 到編程語言中類與類之間的關系 數據庫中表與之間的關系 1 一對一 外鍵,主鍵,唯一約束 A表中的一條數據只能與B表中的一條數據相關聯 2 一對多 外鍵,主鍵 一門課程可以被多個老師所教授 A表中的一條數據可以與B表中的任意多條數據相關聯,反之,B表中的一條數據只能與A表中的一條數據相關聯 3 多對多 通過第三張關聯表去關聯兩張表 A 表中的一條數據可以與B表中的任意多條數據相關聯,B表中的一條數據也可以與A表中的任意多條數據相關聯 3 ORM優點 1 封裝了數據庫中所有的操作,大大提高了開發效率 2 可以省略龐大的數據訪問層,即便不用SQL編碼也能完成對數據的CRUD的操作 3 Flas 中的ORm框架 1 數據庫和框架配置 在python 和 Flask中,使用的ORM框架是 - SqlAlchemy 在Flask 中想使用SqlAlchemy的話,需要進行安裝 pip3 install sqlalchemy pip3 install flask-sqlalchemy 2 創建數據庫 flask from flask import Flask from flask_sqlalchemy import SQLAlchemy app = Flask(__name__) app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://用戶名:密碼@localhost:3306/數據庫名' db = SQLAlchemy(app) app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:liu@176.215.155.241:3306/flask?charset=utf8' app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN'] = True #指定執行完操作后自動提交
app.config["SECRET_KEY"]='zhelizuibianxie'
模型 : 1 定義模型 模型:數據庫中的表在編程語言中的體現,其本質就是一個python類(模型類 或實體類) class MODELMANE(db.Models) __tablename__= 'TABLENAME' COLUMN_NAME = db.Column(db.TYPE,OPTIONS) 1 MODELMANE : 定義模型類的名稱,根據表名設定 2 TABLENAME : 映射到數據庫中表的名稱 3 COLUMN_NAME: 屬性名,映射到數據表就是列名 4 TYPE : 映射到列的數據類型 5 OPTIONS:列選項 db.TYPE如下 類型名 python類型 說明 Integer int 普通整數,32位 SamllInteger int 小范圍整數,通常16位 BigInteger int或long 不限精度整數 float float 浮點數 Numeric decimal.Decimal 定點數 String str 變長字符串 Text str 變長字符串,優化 Unicode unicode 變長Unicode字符串 UnicodeText unicode 優化后的變長Unicode串2 Date datetime.date 日期 Time datetime.time 時間 DateTime datetime.datetime 日期和時間 OPTIONS 列選項 選項名 說明 primary_key 如果設置為True表示該列為主鍵 unique 如果設置為True表示該列值唯一 index 如果設置為True表示該列要創建索引 mullable 如果設置為True表示該列允許為空 default 表示該列的默認值 出錯選項【no modul name mysql_db】 解決1 : import pymysql pymysql.install_as_MySQLdb() 解決2: 在連接路徑上 'mysql+pymysql://root:liu@176.215.155.241:3306/flask?charset=utf8' # 在mysql后面 添加【'+pymysql'】 1 數據庫操作 - 插入 1 創建實體對象 2 完成插入 db.session.add(實體對象) db.session.commit() 2 數據庫操作--查詢 1 基於db.session進行查詢 1 db.session.query() 該函數會返回一個query對象,類型為BaseQuery 該對象中包含了實體類對應的表中的所有的數據 該函數可以接收一個或多個參數,參數們表示的是查詢的實體對象是誰 2 查詢執行函數 目的:在query()的基礎上得到最終想要的結果 語法:db.session.query(),查詢執行函數() 函數 說明 all() 以列表的方式返回query()中所有查詢的結果 first() 返回查詢結果中的第一個結果,如果沒有結果,則返回None first_or_404() 返回查詢結果中的第一個結果,如果沒有結果,則終止並返回404 3 查詢過濾器函數 作用:在查詢的基礎上,篩選部分行數據 語法:db.session.query().過濾器函數().查詢執行函數() 過濾器函數 說明 filter() 按指定條件進行過濾(多表,單表,定位) filter_by() 按等值條件過濾時使用 limit() 按限制行數獲取 order_by() 根據指定條件進行排序 group_by() 根據指定條件進行分組 過濾器函數詳解 1 filter() 注意:條件必須由 模型類,屬性 構成 1 查詢年齡大於30的User的信息 db.session.query(User).filter(User.age>30) 2 查詢年齡大於30並且ID大於1的User的信息 db.session.query(User).filter(User.age>30,User.id>1) 3 查詢年齡大於30或者id 大於1的Users的信息 注意:查詢或的操作,要借助於 or_ db.session.query(Users).filter(or_(Users.age>30,Users.id>2)) 4 查詢ID等於2 的信息的必須用 == 5 查詢email 中包含‘w’的Users的信息,模糊查詢 注意:模糊查詢like需要使用實體類中屬性提供的like() db.session.query(Users).filter(Users.email.like('%w')) 6 查詢尖id在[32,33]的值 需要使用實體類中屬性提供的in_([]) db.session.query(Users).filter(Users.age.in_([32,33])) 2 聚合函數 db.session.query(func.聚合函數('列名').label('別名')) 聚合函數: sum() count() max() min() avg() 3 filter_by() 查詢 id =5 的 Users的信息 db.session.query(Users).filter_by(id=5).all() 4 limit() db.session.query(Users).limit(2) db.session.query(Users).limit(2).offset(1) 5 order_by() #按照id 列的值降序排列 db.session.query(Users).order_by('id desc') # 按照age列 的值降序排序,二級排序按照id升序排序 db.session.query(Users).order_by('id desc,id asc').all() 2 基於Models 類進行查詢 Models.query.查詢過濾器函數(條件參數),查詢執行函數() 3 刪除 1 查詢出要刪除的實體對象 db.session.query(Models).filter_by(xxx).first() 2 根據提供的 刪除方法進行刪除 db.session.delete(u) 注意: 真正的刪除並不是通過刪除操作完成,而是通過修改完成的 4 修改 1 查 將 要修改的信息查詢出來 2 改 實體對象。屬性 =3 保存 db.session.add(實體對象) 2 關系映射 1 一對多 語法:db 1 在:“多”的實體中 增加一個列,引用自’一‘表的主鍵列,外鍵列名 = db.Column() 外鍵列名 = db.Column(db.Integer,db.ForeignKey('主鍵表.列')) 2 在‘一’的實體中 增加關聯屬性以及反向引用關系 et: 關聯屬性: 在course對象中,通過一個屬性能夠得到對應的所有的teacher們 關聯屬性,是應該加載Course的實體類中 反向引用: 在 student對象中,通過一個屬性能夠得到對應的course 反向引用關系屬性,是應該加在 Teacher 的實體類中 增加關聯屬性和反向引用關系: 屬性名= db.relationship('多表實體類名',關系選項) 關系選項 選項名 說明 backref 在關系的另一個模型中添加的反向引用屬性名 (准備在“多”的實體中增加對“一”的實體引用的屬性名) lazy 指定如何加載當前的相關記錄 ... select:首次訪問時加載記錄 immediate:源對象加載后馬上加載相關數據 subquery:效果同上,利用子查詢方式加載記錄 (數據量大的時候,這個子查詢效果更好) noload: 永不加載記錄 dynamic:默認不加載記錄,但會提供加載記錄的查詢 uselist 如果設置為 Flase ,表示不使用列表表示關聯數據,而使用標量 secondary 指定多對多關系映射中的關聯表的名字
from flask import Flask
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
db = SQLAlchemy(app)
app.config['SQLALCHEMY_DATABASE_URI']= 'mysql+pymysql://root:liu@176.215.155.241:3306/flask'
app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN'] = True

class Course(db.Model):
    __tablename__='course'
    id = db.Column(db.Integer,primary_key=True)
    cname = db.Column(db.String(30),nullable=True)
    #增加關聯屬性和反向引用關系
    # 關聯屬性在course對象中通過哪個屬性能夠得到對應的所有的teacher
    #反向引用關系:在teacher對象中通過哪個屬性能找到它對應的course
    teachers = db.relationship('Teacher',backref ='course',lazy ='dynamic')

    def __init__(self,name):
        self.cname=name

    def __repr__(self):
        return '<Coure:%r>'%self.cname

class Teacher(db.Model):
    __tablename__='teacher'
    id = db.Column(db.Integer,primary_key=True)
    tname = db.Column(db.String(30),nullable=True)
    tage = db.Column(db.Integer)
    course_id = db.Column(db.Integer,db.ForeignKey('course.id'))
    def __repr__(self):
        return '<Teacher %r>'%self.name

db.create_all()


@app.route('/')
def hello_world():
    return 'Hello World!'

@app.route('/01-addcourse')
def add_course():
    course1 = Course('python基礎')
    course2 = Course('python高級')
    course3 = Course('數據基礎')
    db.session.add(course1)
    db.session.add(course2)
    db.session.add(course3)
    return '1'

@app.route('/02-register')
def register_teacher():
    teacher = Teacher()
    teacher.tname='呂老師'
    teacher.tage = 28
    course = Course.query.filter_by(id=3).first()
    # teacher.course = course #通過關聯屬性course對象賦值
    teacher.course_id = 1
    db.session.add(teacher)
    return '1'

@app.route('/03-query-teacher')
def query_teacher():
    # 通過 course 查找對應的所有的老師們
    # 查找course_id 為1的course對象
    # course = Course.query.filter_by(id=1).first()
    # print(course.cname)
    # for tea in course.teachers.all():
    #     print(tea.tname)

    #通過teacher 查找對應的course
    teacher = Teacher.query.filter_by(id=1).first()
    print('老師姓名',teacher.tname)
    course = teacher.course
    print(course.cname)

    pass


if __name__ == '__main__':
    app.run(debug=True)
View Code--反向映射並查詢
 
         

 

        2 一對一
          1 什么是一對一
            A表中的一條記錄只能與B表中的一條記錄相關聯
            B表中的一條記錄只能與A表中的一條記錄相關聯
          2 在SQLALchemy 中的體現
            1 在任意一個類中增加
              外鍵列名 = db.Column(db.Integer,db.ForeignKey('主鍵表.主鍵列'))
            2 在另外一個類中增加
              關聯屬性和 反向引用關系屬性
              屬性 = db.relationship('關聯的實體類',backref='反向引用屬性名',uselist=False)
數據庫中的一行:實體 實體完整性:表中的實體不能完全重復
-主鍵

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM