2018-12-19 通過ORM對數據庫進行CRUD操作

一、配置數據庫

    app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:123456@127.0.0.1:3306/flaskdb7'
    app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = Flase
    app.init_app(app)

二、創建模型

from flask_script import SQLAlchemy

# 創建一個sqlalchemy對象
db = SQLAlchemy()

class Student(db.Model):
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    name = db.Column(db.String(31), unique=True, nullable=True)
    phone = db.Column(db.String(11), nullable=True)

    age = db.Column(db.Integer, nullable=Flase)
    gender = db.Column(db.Integer, default=1)

    # flask默認表明就是模型名小寫,如果你不需要改變表明就可以不用設置

    __tablename__ = 'tb_student'

??模型定義中支持的數據類型

類型 說明
Integer 整數
String 字符串類型(在某些數據庫中是可選的如:PostgreSQL)
Text 長文本
DateTime 日期和時間,表示為Python中的datetime對象
float 浮點數
Boolean 布爾值

三、對數據庫進行CRUD操作

3.1 增加數據

    在flask中增加數據需要用到SQLAlchemy的一個session回話,這里的session并不是flask請求和響應的回話session

    添加數據需要用到
    session.add(對象)  # 將對象添加到session中
    session.commit()   # 提交session(可以理解成提交事務,如果未提交,則所有數據都未添加到數據庫)

a. 增加一條

    # 獲取一個學生對象
    stu = Student()
    stu.name = '小明'
    stu.phone = '12345612345'
    stu.age = 16
    # 添加對象到session中
    db.session.add(stu)
    # 提交事務
    db.session.commit()

b. 增加多條

    通過db.session.add_all()實現

    stus = []
    # 循環產生多個學生對象
    for _ in range(10):
        stu = Student()
        # 這里可能會重復
        stu.name = '小明%s' % random.randint(1, 1000)
        stu.age = random.randint(16, 28)
        stu.phone = '12345123451'
        # 把視圖添加到stus列表中
        stus.append(stu)
    # 調用add_all()方法
    db.session.add_all(stus)
    # 提交事務
    db.session.commit()

3.2 修改數據

    修改類似于添加,先過濾出需要修改的學生對象,然后在修改相應的字段

    # 通過filter過濾出對象
    stu = Student.query.filter(Student.id == id).first()
    stu.name = username
    stu.phone = phone
    stu.age = age
    # 將對象添加到sqlalchemy中
    db.session.add(stu)
    # 提交事務
    db.session.commit()

    修改數據時 db.session.add(stu) 可以不寫

3.3 刪除數據

    通過調用delete方法
    db.session.delete(對象)

    # 過濾出學生對象
    stu = Student.query.fliter(Student.id == id).firts()
    # 調用delete方法
    db.session.delete(stu)
    # 提交事務
    # db.session.commit()

3.4 查詢操作

3.4.1 filter和get過濾

    # 查詢指定id的學生信息 filter()
    # 模型.query.filter(模型.字段 == 值)
    stu = Student.query.filter(Student.id == 3).first()
    
    # 查詢指定id的學生信息 filter_by()
    stu1 = Student.query.filter_by(id=3).first()
    
    # 查詢指定id的學生信息 get(pk), 只能查詢主鍵,只能查出一條數據,返回一個查詢對象
    # 主鍵不存在不會報錯,這與Django有區別
    stu3 = Student.query.get(3)
    

    在filter過濾中
    first()  獲取查詢集中的第一個查詢對象
    last()   獲取查詢集中的最后一個查詢對象

3.4.2 查詢所有

    # 查詢所有的數據 all(), 返回一個列表
    stus = Student.query.all()

3.4.3 對查詢集進行排序

    # 排序 升序 默認就是升序 order_by('字段/-字段') order_by('字段 asc/desc')
    stus = Student.query.order_by('age')
    stus = Student.query.order_by('age asc')
    
    # 排序 降序
    stus = Student.query.order_by('-age')
    stus = Student.query.order_by('age desc')
    
    # 實現簡單分頁 offset(m).limit(n) 跳過每條看(截取)n條數據
    stus = Student.query.offset(0).limit(2)

3.4.3 模糊查詢

    # contains('字符') 包含
    stus = Student.query.filter(Student.name.contains('哈')).all()
    
    # 以什么開頭 startswith('字符')
    stus = Student.query.filter(Student.name.startswith('哈')).all()
    
    # 以什么結尾 endswith('字符')
    stus = Student.query.filter(Student.name.endswith('4')).all()
    
    # 第二位以'明'的學生 like() _(下劃線): 匹配一個字符,% 通配符匹配多個字符
    stus = Student.query.filter(Student.name.like('_明%')).all()
    
    # 查詢在某個范圍內的學生信息 模型.id.in_(列表)
    stus = Student.query.filter(Student.id.in_([1, 5, 16, 18]))

3.4.4 條件和邏輯運算組合查詢

    # 條件查詢
    # lt le gt ge 小于、小于等于、大于、大于等于
    stus = Student.query.filter(Student.age.__le__(22)).all()
    
    # 條件查詢可以寫 <  <=  >  >= ==
    stus = Student.query.filter(Student.age <= 22).all()
    
    # 條件組合查詢
    # 年齡小于22, 姓名以6結束 
    # 且關系可以用鏈式過濾的方法實現
    stus = Student.query.filter(Student.age < 22).filter(Student.name.endswith('0')).all()
        
    # 且 關系,用逗號隔開也是且關系
    stus = Student.query.filter(Student.age < 22, Student.name.endswith('0')).all()
    
    除了上面的方法還可以用sqlalchemy庫里面提供的方法實現 且、或、非關系
    # from sqlalchemy import and_, or_, not_

    # 且 and_ 
    stus = Student.query.filter(and_(Student.age < 22,Student.name.endswith('0'))).all()
    
    # 或 or_
    stus = Student.query.filter(or_(Student.age < 22,Student.name.endswith('0'))).all()
    
    # 非 not_
    stus = Student.query.filter(not_(Student.age == 22)).all()

3.4.5 使用paginator進行分頁

    # paginator分頁
    
    # 獲取學生信息,all()返回一個列表
    students = Student.query.all()
    
    # 從get請求中獲取頁碼,也就是請求第幾頁
    page = int(request.args.get('page', 1))
    
    # 將上面查詢出的所有student列表丟給paginate分頁
    paginate = Student.query.paginate(page, 5)
    
    # 在paginate方法中
    paginate(頁碼, 每頁數據條數據)
    
    # 獲取當前頁(page)的數據列表,該方法返回一個列表,這與Django不一樣,如果不用items,paginate是一個不能迭代的對象
    students = paginate.items

??flask中的paginate分頁中的一些方法

方法 說明
paginate.has_prev 判斷是否有上一頁
paginate.has._next 判斷是否有下一頁
paginate.pages 返回總的頁數
paginate.page_num 返回當前頁的頁碼
paginate.prev_num 返回上一頁的頁碼
paginate.next_num 返回下一頁的頁碼
paginate.iter_pages() 返回總的頁碼,可迭代
paginate.total 返回總的數據條數

四、模板解析地址

4.1 無參數的反向解析url

    假設藍圖對象為
    blue = Blueprint('app', __name__)
    則反向解析
    {{ url_for('app.需要跳轉到的函數名') }}
    {{ url_for('app.stu_list') }}

4.2 有參數的反向解析url

    {{ url_for('藍圖對象第一個參數.需要跳轉到的函數名', 參數名 = 值) }}
    # 編輯id=3的學生信息
    {{ url_for('app.edit_stu', id=3) }}

    get方式向服務器提交數據時的反向解析
    {{ url_for('藍圖的第一個參數.需要跳轉到的函數名') }}?參數名=值
    
    如分頁中需要看第i頁則如下:
    {{ url_for('app.stu_list')}}?page={{ i }}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容