Flask-數據庫操作


一、什么是ORM

  • ORM 全拼Object-Relation Mapping. 稱為對象-關系映射
  • 主要實現模型對象到關系數據庫數據的映射.
    • 比如:把數據庫表中每條記錄映射為一個模型對象

關系映射

二、Flask-SQLAlchemy安裝及設置

1. 安裝

  • 安裝 flask-sqlalchemy
pip install flask-sqlalchemy
  • 如果連接的是 mysql 數據庫,需要安裝 mysqldb
pip install flask-mysqldb

提示: 如果flask-mysqldb安裝不上,推薦安裝, pip install pymysql

2. 數據庫連接設置

  • 設置數據庫的鏈接地址,追蹤信息
  • 格式:mysql://<用戶名>:<密碼>@:<端口>/數據庫名稱
# 數據庫鏈接地址
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:mysql@127.0.0.1:3306/test'
# 動態追蹤修改設置,如未設置只會提示警告
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True

查看映射的sql語句,設置: app.config['SQLALCHEMY_ECHO'] = True

  • 配置完成需要去 MySQL 中創建項目所使用的數據庫
$ mysql -uroot -pmysql
$ create database test charset utf8;
from flask import Flask
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)

#2.設置數據庫的配置信息
#設置數據庫的鏈接信息,
app.config["SQLALCHEMY_DATABASE_URI"] = "mysql+pymysql://root:123456@127.0.0.1:3306/test"
#該字段增加了大量的開銷,會被禁用,建議設置為False
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False


#3.創建sqlalchemy對象db,關聯app
db = SQLAlchemy(app)

# 4.編寫模型類,字段,繼承自db.Model
class Student(db.Model):
    __tablename__ = "students"
    #主鍵, 參數1: 表示id的類型, 參數2: 表示id的約束類型
    id = db.Column(db.Integer,primary_key=True)
    name = db.Column(db.String(32))

@app.route('/')
def hello_world():

    return "helloworld"

if __name__ == '__main__':

    #刪除繼承自db.Model的表
    db.drop_all()

    #5.創建數據庫的表,創建的是繼承自db.Model的表
    db.create_all()

    app.run(debug=True)

三、數據庫基本操作

  • 在Flask-SQLAlchemy中,插入、修改、刪除操作,均由數據庫會話管理。
    • 會話用 db.session 表示。在准備把數據寫入數據庫前,要先將數據添加到會話中然后調用 db.session.commit() 方法提交會話。
  • 在 Flask-SQLAlchemy 中,查詢操作是通過 query 對象操作數據。
    • 最基本的查詢是返回表中所有數據,可以通過過濾器進行更精確的數據庫查詢。

1. 增刪改

"""
增刪改

- 全部都是使用db.session操作
- 常見方法:
  - db.session.add(obj) 添加單個對象
  - db.session.add_all([obj1,obj2]) 添加多個對象
  - db.session.delete(obj) 刪除單個對象
  - db.session.commit() 提交會話
  - db.drop_all() 刪除繼承自db.Model所有表
  - db.create_all() :創建繼承自db.Model的所有表
  - 其他:
    - db.session.rollback() 回滾
    - db.session.remove() 移除會話
  - 案例: 編寫兩個模型類, 一個角色模型類,  還有一個用戶模型類
    - 關系: 一對多

"""
from flask import Flask
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)

#1.設置數據庫的配置信息
app.config["SQLALCHEMY_DATABASE_URI"] = "mysql+pymysql://root:123456@127.0.0.1:3306/test"
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False

#2.創建SQLalchemy對象,關聯app
db = SQLAlchemy(app)

#3.編寫模型類
#角色(一方)
class Role(db.Model):
    __tablename__ = "roles"
    id = db.Column(db.Integer,primary_key=True)
    name = db.Column(db.String(32))

    #如果一個類繼承自object那么重寫__str__方法即可, 如果是繼承自db.Model那么需要重寫__repr__方法
    def __repr__(self):
        return "<Role:%s>"%self.name

#用戶(多方)
class User(db.Model):
    __tablename__ = "users"
    id = db.Column(db.Integer,primary_key=True)
    name = db.Column(db.String(32))

    #建立外鍵
    role_id = db.Column(db.Integer,db.ForeignKey(Role.id))

    #如果一個類繼承自object那么重寫__str__方法即可, 如果是繼承自db.Model那么需要重寫__repr__方法
    def __repr__(self):
        return "<User:%s>"%self.name

@app.route('/')
def hello_world():

    return "helloworld"

if __name__ == '__main__':

    #為了演示方便,先刪除表,后創建
    db.drop_all()
    db.create_all()

    app.run(debug=True)

使用ipython進行測試,前提是先進行安裝

2. 查詢

# -*- coding = utf-8 -*-
# @Time : 2020/10/2 10:15
# @Author : md

'''

查詢練習
'''

from flask import Flask
from flask_sqlalchemy import SQLAlchemy


app = Flask(__name__)


# 1.設置數據庫的配置信息
app.config["SQLALCHEMY_DATABASE_URI"] = "mysql+pymysql://root:123456@127.0.0.1:3306/test"
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
# app.config["SQLALCHEMY_ECHO"] = True


# 2.創建SQLalchemy對象,關聯app
db = SQLAlchemy(app)


# 3.編寫模型類
# 角色(一方)
class Role(db.Model):
    __tablename__ = "roles"
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(32))

    # 關系數據寫在這個表中,也就是寫在一方這個表中
    # 為了查詢方便,不會產生實體字段
    # 給role添加了一個users屬性, 那么查詢的方式是, role.users
    # 給user添加了一個role屬性, 那么查詢的方式是, user.role

    # 重點 建立關系,這里的名字為想要建立關系的模型名字
    # 解釋:前半句話是給Role(本模型)模型添加一個users屬性,因為這兩個數據庫通外鍵連接
    # 所以,可以通過這個表的對象,就可以訪問User表中的數據,例如:查看角色是admin的所有用戶role.users
    # 后半句是給本(自己)模型添加一個role屬性,這樣User表中的對象,就可以訪問本表中的數據,可以知道某個用戶是什么身份
    # 例如查看用戶的身份,user.role
    # lazy="dynamic" 是懶加載
    # backref反向引用
    users = db.relationship("User", backref="role", lazy="dynamic")

    # 如果一個類繼承自object那么重寫__str__方法即可, 如果是繼承自db.Model那么需要重寫__repr__方法
    def __repr__(self):
        return "<Role:%s>" % self.name


# 用戶(多方)
class User(db.Model):
    __tablename__ = "users"
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(32))
    email = db.Column(db.String(32))
    password = db.Column(db.String(32))

    # 建立外鍵
    role_id = db.Column(db.Integer, db.ForeignKey(Role.id))

    # 如果一個類繼承自object那么重寫__str__方法即可, 如果是繼承自db.Model那么需要重寫__repr__方法
    def __repr__(self):
        return "<User:%s,%s,%s,%s>" % (self.id, self.name, self.email, self.password)

@app.route('/')
def hello_world():

    return "helloworld"


if __name__ == '__main__':

    # 為了演示方便,先刪除表,后創建
    db.drop_all()
    db.create_all()

    # 創建測試數據
    ro1 = Role(name='admin')
    db.session.add(ro1)
    db.session.commit()

    # 再次插入一條數據
    ro2 = Role(name='user')
    db.session.add(ro2)
    db.session.commit()

    # 多條用戶數據
    us1 = User(name='wang', email='wang@163.com', password='123456', role_id=ro1.id)
    us2 = User(name='zhang', email='zhang@189.com', password='201512', role_id=ro2.id)
    us3 = User(name='chen', email='chen@126.com', password='987654', role_id=ro2.id)
    us4 = User(name='zhou', email='zhou@163.com', password='456789', role_id=ro1.id)
    us5 = User(name='tang', email='tang@itheima.com', password='158104', role_id=ro2.id)
    us6 = User(name='wu', email='wu@gmail.com', password='5623514', role_id=ro2.id)
    us7 = User(name='qian', email='qian@gmail.com', password='1543567', role_id=ro1.id)
    us8 = User(name='liu', email='liu@itheima.com', password='867322', role_id=ro1.id)
    us9 = User(name='li', email='li@163.com', password='4526342', role_id=ro2.id)
    us10 = User(name='sun', email='sun@163.com', password='235523', role_id=ro2.id)
    db.session.add_all([us1, us2, us3, us4, us5, us6, us7, us8, us9, us10])
    db.session.commit()

    app.run(debug=True)
  • 其中realtionship描述了Role和User的關系。
  • 第一個參數為對應參照的類"User"
  • 第二個參數backref為類User,反向引用屬性

第三個參數lazy決定了什么時候SQLALchemy從數據庫中加載數據

  • 如果設置為子查詢方式(subquery),則會在加載完Role對象后,就立即加載與其關聯的對象,這樣會讓總查詢數量減少,但如果返回的條目數量很多,就會比較慢
    • 設置為 subquery 的話,role.users 返回所有數據列表
  • 另外,也可以設置為動態方式(dynamic),這樣關聯對象會在被使用的時候再進行加載,並且在返回前進行過濾,如果返回的對象數很多,或者未來會變得很多,那最好采用這種方式

User.query.filter().all()

3. 查詢練習

查詢所有用戶數據
User.query.filter().all()
此時過濾器可以不寫
User.query.all()


查詢有多少個用戶
User.query.count()



查詢第1個用戶
User.query.first()


查詢id為4的用戶[3種方式]
User.query.get(4) 此時get里面是主鍵

 User.query.filter(User.id == 4).all() 返回的是列表,但滿足的只有一個

User.query.filter(User.id == 4).first()

User.query.filter_by(id=4).first()




查詢名字結尾字符為g的所有數據[開始/結尾/包含]
User.query.filter(User.name.startswith('g')).all()

 User.query.filter(User.name.endswith('g')).all()

User.query.filter(User.name.contains('g')).all()


查詢名字不等於wang的所有數據
User.query.filter(User.name != 'wang').all()


查詢名字和郵箱都以 li 開頭的所有數據
User.query.filter(User.name.startswith('li'),User.email.startswith('li')).all()


查詢password是 123456 或者 email 以 itheima.com 結尾的所有數據
from sqlalchemy import or_
User.query.filter(or_(User.password == '123456',User.email.endswith('itheima.com'))).all()



查詢id為 [1, 3, 5, 7, 9] 的用戶列表
User.query.filter(User.id.in_([1,3,5,7,9])).all()


查詢name為liu, 的角色數據
user = User.name.filter(User.name == 'liu').first()
role = Role.query.filter(Role.id == user.role_id).first()


查詢所有用戶數據,並以郵箱排序
 User.query.order_by(User.email).all()
 User.query.order_by(User.email.desc()).all()





每頁3個,查詢第2頁的數據

#page: 表示要查詢的頁數
#per_page: 表示每頁有多少條數據
#Error_out: 建議寫成False,查不到不會報錯
paginate = User.query.paginate(page,per_page,Error_out)

paginate.pages #總頁數
paginate.page #當前頁
paginate.items #當前的對象列表


查詢前兩條數據
 User.query.limit(2).all()


lazy="dynamic"

四、綜合案例-圖書管理

目的:

  • 表單創建
  • 數據庫操作
  • 一對多關系演練

實現步驟:

  • 1.創建數據庫配置信息,定義模型類
  • 2.創建數據庫表,添加測試數據
  • 3.編寫html頁面,展示數據
  • 4.添加數據
  • 5.刪除書籍,刪除作者

1. 圖書館測試數據顯示

  • 步驟
    • 1.查詢所有作者信息
    • 2.攜帶作者信息,渲染頁面

2. 圖書館添加數據

  • 添加的邏輯分析:
    • 1.如果作者存在,書籍存在, 不能添加
    • 2.如果作者存在,書籍不存在,可以添加
    • 3.如果作者不存在,可以添加

3. 圖書館刪除書籍

  • 步驟
    • 1.根據書籍編號獲取書籍對象
    • 2.刪除書籍對象
    • 3.重定向到頁面展示

4. 圖書館刪除作者

  • 步驟
    • 1.根據作者編號獲取作者對象
    • 2.遍歷刪除,作者書籍對象
    • 3.刪除作者,提交數據庫
    • 4.重定向到頁面展示

5. 圖書館CSRFProtect應用

  • 作用: 防止csrf攻擊的
  • 使用步驟:
    • 1.導入類CSRFProtect
    • 2.使用CSRFProtect保護app
      • 一旦使用POST,PUT,DELTE,PATCH方式提交的時候就需要校驗csrf_token
    • 3.需要設置SECRET_KEY,用來加密csrf_token
    • 4.設置csrf_token到表單中

6. 表單的創建

# -*- coding = utf-8 -*-
# @Time : 2020/10/2 16:07
# @Author : md


from flask import Flask, render_template, request, redirect, flash
from flask_sqlalchemy import SQLAlchemy
from flask_wtf.csrf import CSRFProtect

app = Flask(__name__)

# 由於使用了flash,所以得設置
app.config["SECRET_KEY"] = "wepricsjf"

# 使用 CSRFProtect保護app
CSRFProtect(app)


# 1.設置數據庫的配置信息
app.config["SQLALCHEMY_DATABASE_URI"] = "mysql+pymysql://root:123456@127.0.0.1:3306/test"
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
# 生成對應的sql語句在控制台
# app.config["SQLALCHEMY_ECHO"] = True


# 2.創建SQLalchemy對象,關聯app
db = SQLAlchemy(app)


# 3.編寫模型類
# 作者(一方)
class Author(db.Model):
    __tablename__ = "authors"
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(32))

    # 關系數據,必須有外鍵為基礎
    books = db.relationship("Book", backref="author")

    # 如果一個類繼承自object那么重寫__str__方法即可, 如果是繼承自db.Model那么需要重寫__repr__方法
    def __repr__(self):
        return "<Author:%s>" % self.name


# 書籍(多方)
class Book(db.Model):
    __tablename__ = "books"
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(32))

    # 建立外鍵
    author_id = db.Column(db.Integer, db.ForeignKey(Author.id))

    # 如果一個類繼承自object那么重寫__str__方法即可, 如果是繼承自db.Model那么需要重寫__repr__方法
    def __repr__(self):
        return "<Book:%s,%s>" % (self.id, self.name)


# 5. 展示數據
@app.route('/')
def hello_world():
    # 1. 查詢所有的作者信息,因為作者有外鍵,可以通過關系數據方便的查出該作者對應的書籍
    authors = Author.query.all()

    return render_template("library.html", authors=authors)


# 6. 添加數據
@app.route("/add_data", methods=["POST"])
def add_data():
    # 1. 獲取提交的數據
    author_name = request.form.get("author")
    book_name = request.form.get("book")

    # 先判斷輸入的內容是否為空
    if not all([author_name, book_name]):
        flash("作者或書籍不能為空")
        return redirect("/")


    # 2. 根據作者信息查詢作者對象
    author = Author.query.filter(Author.name == author_name).first()
    # 3. 判斷作者是否存在
    if author:
        # 4. 通過書籍名稱查詢書籍對象,並且這本書的作者的id和查詢出來的作者的id一樣
        # 也就是查看要添加的這本書是不是該作者寫的
        book = Book.query.filter(Book.name == book_name, Book.author_id == Author.id).first()
        # 5. 判斷書籍是否存在
        if book:
            # return "該作者已經寫了這本書了"
            flash("已經有該作者寫的這本書了")
        else:
            # 創建書籍對象,添加到數據庫
            book = Book(name=book_name, author_id=author.id)
            db.session.add(book)
            db.session.commit()
    else:
        # 作者不存在也是可以添加的
        # 先在作者表中進行添加
        author = Author(name=author_name)
        db.session.add(author)
        db.session.commit()

        # 然后再書籍表中進行添加
        book = Book(name=book_name, author_id=author.id)
        db.session.add(book)
        db.session.commit()

    # 6. 重定向到首頁
    return redirect("/")


# 7. 刪除書籍
@app.route("/delete_book/<int:book_id>")
def delete_book(book_id):
    # 1. 根據id獲取到書籍對象
    book = Book.query.get(book_id)
    # 2. 刪除這個書籍
    db.session.delete(book)
    db.session.commit()
    # 3. 重定向到頁面
    return redirect("/")


# 7. 刪除作者
@app.route("/delete_author/<int:author_id>")
def delete_author(author_id):
    # 1. 根據id獲取到作者對象
    author = Author.query.get(author_id)
    # 2. 這個作者的全部書籍,由於使用了關系數據,直接這樣寫就可以
    books = author.books
    # 3. 遍歷這個作者的全部書籍
    for book in books:
        db.session.delete(book)
    # 4. 刪除作者
    db.session.delete(author)
    db.session.commit()

    # 5. 重定向到頁面
    return redirect("/")


if __name__ == '__main__':
    # 為了演示方便,先刪除后創建
    db.drop_all()
    db.create_all()

    # 4. 添加測試數據庫
    # 生成數據
    au1 = Author(name='老王')
    au2 = Author(name='老尹')
    au3 = Author(name='老劉')
    # 把數據提交給用戶會話
    db.session.add_all([au1, au2, au3])
    # 提交會話
    db.session.commit()

    bk1 = Book(name='老王回憶錄', author_id=au1.id)
    bk2 = Book(name='我讀書少,你別騙我', author_id=au1.id)
    bk3 = Book(name='如何才能讓自己更騷', author_id=au2.id)
    bk4 = Book(name='怎樣征服美麗少女', author_id=au3.id)
    bk5 = Book(name='如何征服英俊少男', author_id=au3.id)
    # 把數據提交給用戶會話
    db.session.add_all([bk1, bk2, bk3, bk4, bk5])
    # 提交會話
    db.session.commit()

    app.run()

7. library.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

{# action: 提交到的地址, method: 表示提交的方式 #}
<form action="/add_data" method="post">
{# 設置隱藏字段csrf_token , 只要使用了CSRFProtect,然后使用模板渲染的時候就可以直接使用csrf_token()方法#}
    <input type="hidden" name="csrf_token" value="{{ csrf_token() }}">

    作者: <input type="text" name="author"><br>
    書籍: <input type="text" name="book"><br>
    <input type="submit" value="添加"><br>
    {% for message in get_flashed_messages() %}
        <span style="color: red;">{{ message }}</span>
    {% endfor %}
</form>

<hr>

{# 數據展示 #}
<ul>
    {# 遍歷作者 #}
    {% for author in authors %}
{#        <li>作者: {{ author.name }}</li>#}
{#        <li>作者: {{ author.name }} <a href="/delete_author/{{ author.id }}">刪除</a></li>#}
        <li>作者: {{ author.name }} <a href="{{ url_for("delete_author",author_id=author.id) }}">刪除</a></li>

        {# 遍歷作者的書籍 #}
        <ul>
            {% for book in author.books %}
{#                <li>書籍: {{ book.name }} </li>#}
                <li>書籍: {{ book.name }} <a href="/delete_book/{{ book.id }}">刪除</a></li>
            {% endfor %}

        </ul>
    {% endfor %}

</ul>



</body>
</html>

五、多對多

在項目開發過程中,會遇到很多數據之間多對多關系的情況,比如:

  • 學生網上選課(學生和課程)
  • 老師與其授課的班級(老師和班級)
  • 用戶與其收藏的新聞(用戶和新聞)
  • 等等...

所以在開發過程中需要使用 ORM 模型將表與表的多對多關聯關系使用代碼描述出來。多對多關系描述有一個唯一的點就是:需要添加一張單獨的表去記錄兩張表之間的對應關系

1. 需求分析

  • 學生可以網上選課,學生有多個,課程也有多個
  • 學生有:張三、李四、王五
  • 課程有:物理、化學、生物
  • 選修關系有:
    • 張三選修了化學和生物
    • 李四選修了化學
    • 王五選修了物理、化學和生物

需求:

  1. 查詢某個學生選修了哪些課程
  2. 查詢某個課程都有哪些學生選擇

2. 代碼

# -*- coding = utf-8 -*-
# @Time : 2020/10/2 19:30
# @Author : md


'''
多對多,學生和課程
'''

from flask import Flask
from flask_sqlalchemy import SQLAlchemy


app = Flask(__name__)


# 1.設置數據庫的配置信息
app.config["SQLALCHEMY_DATABASE_URI"] = "mysql+pymysql://root:123456@127.0.0.1:3306/test"
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
# app.config["SQLALCHEMY_ECHO"] = True


# 2.創建SQLalchemy對象,關聯app
db = SQLAlchemy(app)


# 3.編寫模型類
# 學生
class Student(db.Model):
    __tablename__ = "students"
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(32))

    # 關系數據,使用在多對多中的時候注意secondary這個屬性,是中間表的表名,用來二次查詢
    courses = db.relationship("Course", backref="students", secondary="td_student_course")

    # 如果一個類繼承自object那么重寫__str__方法即可, 如果是繼承自db.Model那么需要重寫__repr__方法
    def __repr__(self):
        return "<Role:%s>" % self.name


# 課程
class Course(db.Model):
    __tablename__ = "courses"
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(32))

    # 如果一個類繼承自object那么重寫__str__方法即可, 如果是繼承自db.Model那么需要重寫__repr__方法
    def __repr__(self):
        return "<User:%s>" % self.name


# 中間表
db.Table(
    "td_student_course",
    db.Column("student_id", db.Integer, db.ForeignKey(Student.id)),
    db.Column("course_id", db.Integer, db.ForeignKey(Course.id))
)

@app.route('/')
def hello_world():

    return "helloworld"



# 為了演示,先刪除后創建
db.drop_all()
db.create_all()

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

cou1 = Course(name='物理')
cou2 = Course(name='化學')
cou3 = Course(name='生物')

stu1.courses = [cou2, cou3]
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()


if __name__ == '__main__':
    app.run()

六、數據庫遷移

  • 目的: 當數據庫的表結構發生變化之后,如果直接刪除原有的數據,再添加新的數據,有可能導致數據丟失
  • 注意點:
    • 1.是為了備份表結構,而不是數據
    • 2.如果想要備份數據,需要使用工具,navicat,mysqlworkbench,等等
    • 3.更新的過程數據一般不會丟失,做降級的時候需要謹慎操作
  • 操作流程:
    • 1.安裝擴展
      • pip install flask_script
      • pip install flask_migrate
    • 2.導入三個類
      • from flask_script import Manager
      • from flask_migrate import Migrate, MigrateCommand
    • 3.通過Manager類創建對象manager,管理app
      • manager = Manager(app)
    • 4.使用Migrate,關聯db,app
      • Migrate(app,db)
    • 5.給manager添加一條操作命令
      • manager.add_command("db",MigrateCommand)
    • 相關遷移命令:
      • 生成遷移文件夾[一次就好]
        • python xxx.py db init
      • 將模型類生成遷移腳本[重復執行]
        • python xxx.py db migrate -m '注釋'
      • 將遷移腳本更新到數據庫中[重復執行]
        • python xxx.py db upgrade/downgrade [version]
      • 其他命令
        • 查看最新版本的命令
          • python xxx.py db show
        • 查看當前版本
          • python xxx.py db current
        • 查看所有的歷史版本
          • python xxx.py db history
# -*- coding = utf-8 -*-
# @Time : 2020/10/2 20:38
# @Author : md

from flask import Flask
from flask_script import Manager
from flask_migrate import Migrate, MigrateCommand
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)

# 設置數據庫配置信息
app.config["SQLALCHEMY_DATABASE_URI"] = "mysql+pymysql://root:123456@localhost:3306/test1"
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False

# 創建SQLAlchemy對象,關聯app
db = SQLAlchemy(app)


# 3. 通過Manager類創建對象manager,管理app
manager = Manager(app)

# 4.使用Migrate,關聯db,app
Migrate(app, db)

# 5.給manager添加一條操作命令
manager.add_command("db", MigrateCommand)


# 6.編寫模型類
class Student(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(32))
    age = db.Column(db.Integer)
   # email = db.Column(db.String(32))


@app.route('/')
def hello_world():
    return "helloworld"


if __name__ == '__main__':
    manager.run()

生成遷移文件夾

將模型類生成遷移腳本

將遷移腳本更新到數據庫中

此時就可以在數據庫中看到對應的表了

此時在代碼中多寫一行,添加一列

然后繼續執行這兩條命令,就會看到數據表結構中就多了一列

還可以進行降級

然后再升級到指定的版本


免責聲明!

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



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