第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

首頁 慕課教程 Flask 框架教程 Flask 框架教程 Flask 的 ORM 模型-應(yīng)用

Flask 的 ORM 模型-應(yīng)用

在上一個小節(jié)中,講解了 ORM 模型的基本概念,并給出一個最小的例子說明如何建立面向?qū)ο笈c關(guān)系數(shù)據(jù)庫之間的映射關(guān)系。本小節(jié)介紹了 SqlAlchemy 的相關(guān) API,通過一個完整的例子,對 mysql 數(shù)據(jù)庫進(jìn)行增、刪、改、查。

1. 功能概述

在本小節(jié),編寫程序 app.py,對一個名稱為 school 的數(shù)據(jù)庫進(jìn)行增、刪、改、查,數(shù)據(jù)庫中存在一張表 students,包含的字段如下:

字段名 類型 描述
sno 整數(shù) 學(xué)號
name 字符串 姓名
age 整數(shù) 年齡

在上一個小節(jié)中,使用 mysql 的命令行創(chuàng)建表 students,在本節(jié)的例子中,為了展示 ORM 的功能,以編程的方式創(chuàng)建表 students。

2. 配置 SQLAlchemy

首先,引入相關(guān)庫,對訪問 mysql 進(jìn)行配置,如下所示:

#!/usr/bin/python3
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
import sys

app = Flask(__name__)
user = 'root'
password = '123456' 
database = 'school'
uri = 'mysql+pymysql://%s:%s@localhost:3306/%s' % (user, password, database)
app.config['SQLALCHEMY_DATABASE_URI'] = uri 

db = SQLAlchemy(app)

在第 1 行到第 4 行,引入庫 flask 和 flask_sqlalchemy;在第 6 行到第 11 行,對 SQLAlchemy 進(jìn)行配置,設(shè)置如下參數(shù):

參數(shù)
user 訪問數(shù)據(jù)庫的用戶,假設(shè)是 root
password 訪問數(shù)據(jù)庫的密碼,假設(shè)是 123456
database 數(shù)據(jù)庫名稱
uri SQLAlchemy 連接數(shù)據(jù)庫的字符串

在第 8 行,對 SQLAlchemy 進(jìn)行配置,SQLALCHEMY_DATABASE_URI 配置的是連接數(shù)據(jù)庫的字符串,在這個例子中,該字符串為:

mysql+pymysql://root:123456@localhost:3306/school

字符串中的 “mysql+pymysql” 表示:數(shù)據(jù)庫類型是 mysql,使用 pymysql 作為訪問 mysql 的底層 API。

最后,在第 13 行,創(chuàng)建 SQLAlchemy 對象,用于映射數(shù)據(jù)庫表和對象。

3. 程序框架

程序包含有 4 個主要功能:

函數(shù)名 功能
create_table 創(chuàng)建表 students
insert_students 在表 students 中插入數(shù)據(jù)
query_students 查詢表 students
update_students 更新表 students 中的數(shù)據(jù)
delete_students 刪除表 students 中的數(shù)據(jù)
class Student(db.Model):
    pass

def create_table():
    pass

def insert_students():
    pass

def query_students():
    pass

def update_students():
    pass

def delete_students():
    pass

command = sys.argv[1]
if command == 'create':
    create_table()
elif command == 'insert':
    insert_students()
elif command == 'query':
    query_students()
elif command == 'update':
    update_students()
elif command == 'delete':
    delete_students()

首先,定義繼承于 db.Model 的類 Student,該類映射數(shù)據(jù)庫中的表 students;然后,分別定義了實現(xiàn)上述功能的函數(shù),在后續(xù)小節(jié)會陸續(xù)填充;最后,例子程序是一個命令行程序,根據(jù)不同的命令行參數(shù)調(diào)用相應(yīng)的功能函數(shù)。

4. 創(chuàng)建表

class Student(db.Model):
    __tablename__ = 'students'
    sno = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(255))
    age = db.Column(db.Integer)

    def dump(self):
        print(self.sno, self.name, self.age)

def create_table():
    db.drop_all()
    db.create_all()

首先,建立表和類的映射關(guān)系:創(chuàng)建類 Student 繼承于 db.Model,表示類 Student 用于映射數(shù)據(jù)庫中的表;設(shè)定 __tablename__ 為 students,表示將類 Student 映射到數(shù)據(jù)庫中的表 students。

然后,建立屬性和字段的映射關(guān)系:映射 sno 到表 students 的字段 sno,類型為整數(shù) (db.Integer),primary_key=True 表示該字段是主鍵; 映射 name 到表 students 的字段 name,類型為整數(shù) (db.String); 映射 age 到表 students 的字段 age,類型為整數(shù) (db.Integer)。

調(diào)用 db.drop_all() 刪除數(shù)據(jù)庫 school 中的所有表格;調(diào)用 db.create_all() 創(chuàng)建已經(jīng)建立映射關(guān)系的表 students,表 students 已經(jīng)被映射到類 Student。

5. 插入數(shù)據(jù)

def insert_students():
    tom = Student(sno = 1, name = 'tom', age = 12)
    db.session.add(tom)
    db.session.commit()

    jerry = Student(sno = 2, name = 'jerry', age = 11)
    mike = Student(sno = 3, name = 'mike', age = 11)
    db.session.add_all([jerry, mike])
    db.session.commit()

在第 2 行,通過類 Student 實例化生成一個實例 tom,調(diào)用 db.session.add(tom) 將該實例加入到數(shù)據(jù)庫連接會話中,調(diào)用 db.session.commit() 提交保存到數(shù)據(jù)庫。

在第 6 行和第 7 行,生成 2 個實例 jerry 和 mike,調(diào)用 db.session.add_all([jerry, mike]) 將兩個實例批量加入到數(shù)據(jù)庫連接會話中,調(diào)用 db.session.commit() 提交保存到數(shù)據(jù)庫。

6. 查詢數(shù)據(jù)

完成查詢表 students 的函數(shù) query_students,該函數(shù)包括 4 個片段:

6.1 查詢所有的學(xué)生

def query_students():
    print('查詢所有的學(xué)生')
    students = Student.query.all()
    for student in students: 
        student.dump()
    print()

類 Student 繼承于類 db.Model,繼承了方法 db.Model.query.all(),該方法查詢表中所有的數(shù)據(jù),無條件返回表中所有的數(shù)據(jù)。

類 Student 映射為表 students,Student.query.all() 返回表 students 中所有的學(xué)生數(shù)據(jù)。

6.2 指定條件查詢

繼續(xù)在函數(shù) query_students 中增加如下代碼:

    print('查詢所有年齡是 11 歲的學(xué)生')
    students = Student.query.filter_by(age = 11)
    for student in students: 
        student.dump()
    print()

類 Student 繼承于類 db.Model,繼承了方法 db.Model.query.filter_by(conidtion),該方法的參數(shù) condition 是查詢條件,返回表中符合條件的數(shù)據(jù)。

類 Student 映射為表 students,Student.filter_by(age = 11) 指明查詢條件為 age = 11, 返回表 students 中所有年齡是 11 歲的學(xué)生。

6.3 查詢第一個符合條件的數(shù)據(jù)

繼續(xù)在函數(shù) query_students 中增加如下代碼:

    print('查詢第一個年齡是 11 歲的學(xué)生')
    students = Student.query.filter_by(age = 11)
    student = students.first()
    student.dump()
    print()

方法 db.Model.query.filter_by(conidtion) 返回一個集合,包括所有滿足條件的數(shù)據(jù)。方法 first() 返回第一個符合條件的數(shù)據(jù)。

6.4 根據(jù)條件組合查詢

繼續(xù)在函數(shù) query_students 中增加如下代碼:

    print('查詢姓名是 jerry 并且年齡是 11 歲的學(xué)生')
    students = Student.query.filter_by(age = 11, name = 'jerry')
    for student in students:
        student.dump()
    print()

在方法 db.Model.query.filter_by(conidtion) 中,參數(shù) condition 可以是多個。filter_by(age = 11, name = ‘jerry’) 表示查詢姓名是 jerry 并且年齡是 11 歲的學(xué)生。

7. 更新數(shù)據(jù)

def update_students():
    students = Student.query.filter_by(name = 'tom')
    students.update({'name':'TOM'})
    db.session.commit()

類 Student 映射為表 students,Student.filter_by(name = ‘tom’) 指明查詢條件為 name = ‘tom’, 返回表 students 中所有姓名是 tom 的學(xué)生。

調(diào)用 update({‘name’: ‘TOM’}) 方法,將所有姓名是 tom 的學(xué)生的姓名更改為 TOM,調(diào)用 db.session.commit() 提交保存到數(shù)據(jù)庫。

8. 刪除數(shù)據(jù)

def delete_students():
    students = Student.query.filter_by(name = 'mike')
    students.delete()
    db.session.commit()

類 Student 映射為表 students,Student.filter_by(name = ‘mike’) 指明查詢條件為 name = ‘mike’, 返回表 students 中所有姓名是 mike 的學(xué)生。

調(diào)用 delete() 方法,將所有姓名是 mike 的學(xué)生從表 students 中刪除,調(diào)用 db.session.commit() 提交保存到數(shù)據(jù)庫。

9. 測試程序

1. 在 mysql 命令行中創(chuàng)建數(shù)據(jù)庫 school

$ sudo mysql
mysql > drop database school;
mysql > create database school;

2. 創(chuàng)建表 students

$ python3 app.py create

3. 向表 students 插入數(shù)據(jù)

$ python3 app.py insert

4. 查詢表 students 中的數(shù)據(jù)

$ python3 app.py query
查詢所有的學(xué)生
1 tom 12
2 jerry 11
3 mike 11

查詢所有年齡是 11 歲的學(xué)生
2 jerry 11
3 mike 11

查詢第一個年齡是 11 歲的學(xué)生
2 jerry 11

查詢姓名是 jerry 并且年齡是 11 歲的學(xué)生
2 jerry 11

結(jié)果顯示,向數(shù)據(jù)庫中插入了 3 個學(xué)生:tom、jerry 和 mike。

5. 更新表 students 中的數(shù)據(jù)

$ python3 app.py update
$ python3 app.py query
查詢所有的學(xué)生
1 TOM 12
2 jerry 11
3 mike 11
...

結(jié)果顯示,姓名為 tom 的學(xué)生的姓名更改為 TOM。

6. 刪除表 students 中的數(shù)據(jù)

$ python3 app.py delete
$ python3 app.py query
查詢所有的學(xué)生
1 TOM 12
2 jerry 11
...

結(jié)果顯示,姓名為 mike 的學(xué)生被刪除。

5. 源代碼下載

6. 小結(jié)

本小節(jié)通過一個具體的實例講解了 SqlAlchemy 的相關(guān) API,使用思維導(dǎo)圖概括如下:

圖片描述

通過本節(jié)的例子,可以看出,與拼接 SQL 語句訪問數(shù)據(jù)庫相比,通過 ORM 進(jìn)行數(shù)據(jù)庫訪問,顯著的提高了代碼的可讀性。