04 Python Flask 教學06 Python 資料庫教學10 所有文章

[Flask教學] Flask-SQLAlchemy -ORM 一對多關聯篇 (三)

一. 前言

▍關於什麼是 ORM 架構

簡單來說是直接用 Python 的語法對資料庫進行操作,不需要直接寫 SQL 語法,ORM 背後會自動將 Python 代碼轉換成應對的 SQL 語法,再來進行對資料庫的操作。

▍關於 ORM 設定和操作更多內容可參考:

二. ORM關聯:一對多

ORM 一對多關聯

▍定義一對多模型

設定其實很簡單:
Step1. 在一對多的一中設定 db.relationship(…) 關係
Step2. 在一對多的多中設定 db.ForeignKey(…) 關係
就完成囉~

▍舉個簡單的栗子 🌰

首先我們定義了 product、add_to_cart、user 這三個模型

from flask import Flask, render_template, request, jsonify
from flask_sqlalchemy import SQLAlchemy
from datetime import datetime

app = Flask(__name__)
# MySql datebase
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.config['SQLALCHEMY_DATABASE_URI'] = "mysql+pymysql://account:[email protected]:3306/db"

db = SQLAlchemy(app)


class Product(db.Model):
    __tablename__ = 'product'
    pid = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(30), unique=True, nullable=False)
    price = db.Column(db.Integer, nullable=False)
    img = db.Column(db.String(100), unique=True, nullable=False)
    description = db.Column(db.String(255), nullable=True)
    state = db.Column(db.String(10), nullable=False)
    insert_time = db.Column(db.DateTime, default=datetime.now, nullable=False)
    update_time = db.Column(
        db.DateTime, onupdate=datetime.now, default=datetime.now, nullable=False)

    db_product_addtocar = db.relationship("AddToCar", backref="product")

    def __init__(self, name, price, img, description, state):
        self.name = name
        self.price = price
        self.img = img
        self.description = description
        self.state = state

class User(db.Model):
    __tablename__ = 'user'
    uid = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(30), unique=True, nullable=False)
    password = db.Column(db.String(255), nullable=False)
    role = db.Column(db.String(10), nullable=False)
    insert_time = db.Column(db.DateTime, default=datetime.now, nullable=False)
    update_time = db.Column(
        db.DateTime, onupdate=datetime.now, default=datetime.now, nullable=False)

    db_user_atc = db.relationship("AddToCar", backref="user")

    def __init__(self, name, password, role):
        self.name = name
        self.password = password
        self.role = role

class AddToCar(db.Model):
    __tablename__ = 'addtocar'
    id = db.Column(db.Integer, primary_key=True)
    quantity = db.Column(db.Integer, nullable=False)
    state = db.Column(db.String(5), nullable=False)
    insert_time = db.Column(db.DateTime, default=datetime.now, nullable=False)
    update_time = db.Column(
        db.DateTime, onupdate=datetime.now, default=datetime.now, nullable=False)

    uid = db.Column(db.Integer, db.ForeignKey('user.uid'), nullable=False)
    pid = db.Column(db.Integer, db.ForeignKey('product.pid'), nullable=False)

    def __init__(self, uid, pid, quantity, state):
        self.uid = uid
        self.pid = pid
        self.quantity = quantity
        self.state = state

看到上方這一長串代碼先別慌,我們只先單純看 Product 和 AddToCar 這兩個部分,他們的關係為一對多 (表示為一個 Product 可以被多個 AddToCar 包含)

首先 Product (一對多的一) 的部分需要設定 db.relationship() 來讓 SQLAlchemy 知道 Product 和 AddToCar 是有關聯的,而 backref=”product” 中的 product 則像是暗號,未來在讀取 AddToCar 表格時,後面只需像這樣加上 AddToCar.product,就可以輕鬆讀取到 Product 表格內的資料囉!

db_product_addtocar = db.relationship("AddToCar", backref="product")

再來 AddToCar (一對多的多) 的部分需要設定 db.ForeignKey() 來告訴 SQLAlchemy 當兩張表連結時要以什麼為外接的 key。

pid = db.Column(db.Integer, db.ForeignKey('product.pid'), nullable=False)

當 db.relationship() 和 db.ForeignKey() 都設定好後,接下來我們就來測試操作資料庫啦~

▍實作操作一對多資料庫

首先我在在資料庫裡面先存入產品( p1~p3 )和使用者( u1 )的資料

# 新增產品
p1 = Product('Isacc', 8888, 'https://picsum.photos/id/1047/1200/600', '', 'Y')
p2 = Product('Dennis', 9999,'https://picsum.photos/id/1049/1200/600', '', 'Y')
p3 = Product('Joey', 7777, 'https://picsum.photos/id/1033/1200/600', '', 'Y')

# 新增使用者
u1 = User('Max', '123456', 'Admin')

db.session.add_all([p1, p2, p3, u1])
db.session.commit()

接著利用剛剛存入的資料,來達成使用者 Max 將 p1 產品加入購物車

# 新增購物車
atc1 = AddToCar(1, 1, 5, 'Y')

db.session.add_all([atc1])
db.session.commit()

成功的話,資料庫的 addtocar 表格就會像是這樣~

那我們來對 addtocar 查詢看看

# 查看
query = AddToCar.query.first()
print(query.product.name)  
print(query.user.name)  

--> # Isacc
--> # Max

恭喜你已經完成一對多的新增和查詢囉~

最後~推薦 Flask 系列文章:

▍關於 Flask 教學系列目錄:

▍關於 Flask 資料庫 SQLAlchemy 文章:

那麼 [Flask教學] Flask-SQLAlchemy -ORM 一對多關聯篇 (三) 結束囉,感謝收看!

有關 Max行銷誌 的最新文章,都會發佈在 Max行銷誌的 Facebook 粉絲專頁,如果想看最新更新,還請您按讚或是追蹤唷!

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *