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

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

一. 前言

▍關於什麼是 ORM 架構

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

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

二. ORM關聯:多對多

ORM 多對多關聯

▍定義多對多模型

設定其實很簡單:
Step1. 設定 db.relationship(…) 關係
Step2. 設定 db.Table(‘relations’…),這設定會自動在資料庫建立新的關聯表
Step3. 在 db.Table(‘relations’…) 內設定 db.ForeignKey(…) 關係
就完成囉~

▍舉個簡單的栗子 🌰

首先我們定義了 product、Tag 這兩個模型,一個產品會有多個 Tag,而一個 Tag 也可能會被多個產品,所以多對多的模式就出現了~

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)

relations = db.Table(
    'relations',
    db.Column('tagid_rt', db.Integer, db.ForeignKey('tag_mul_to_mul.tagid')),
    db.Column('pid_rt', db.Integer, db.ForeignKey('product_mul_to_mul.pid')))


class Product(db.Model):
    __tablename__ = 'product_mul_to_mul'
    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=False)
    state = db.Column(
        db.String(10), nullable=False)
    insert_time = db.Column(db.DateTime, default=datetime.now)
    update_time = db.Column(
        db.DateTime, onupdate=datetime.now, default=datetime.now)

    db_product_tag_rel = db.relationship(
        "Tag", secondary=relations, 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 Tag(db.Model):
    __tablename__ = 'tag_mul_to_mul'
    tagid = db.Column(db.Integer, primary_key=True)
    tag_type = db.Column(db.String(30))
    insert_time = db.Column(db.DateTime, default=datetime.now)
    update_time = db.Column(
        db.DateTime, onupdate=datetime.now, default=datetime.now)

    def __init__(self, tag_type):
        self.tag_type = tag_type
  1. SQLAlchemy中設置多對多關聯時,我們並不需要去特別的定義一個 Model 來做中繼,而是透過Table的方法,來設罝MetaData,並記錄兩個 Model 的ForeignKey使用。
  2. “db.Table(‘relations’…)”的 relations 是待會 SQLAlchemy 會自動生成的關聯表名稱
  3. ” db.Column(‘tagid_rt’…) “則是設定裡面有的欄位

▍實作操作多對多資料庫

首先將資料庫 product_mul_to_mul 表中存進三筆資料,完成後會看到如下圖:

# 建立表格
db.create_all()

# 新增產品
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')

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

再來我們新增兩筆 Tag 的資料到 tag_mul_to_mul 表內,完成後會如下圖:

# 新增商品類型
tag1 = Tag('免運費')
tag2 = Tag('新貨到')

# commit
db.session.add_all([tag1, tag2])
db.session.commit()
tag_mul_to_mul

最後我們將各產品與 Tag 互相帶上關係,完成後如下圖:

# 將商品新增類型
p1.db_product_tag_rel = [tag1, tag2]
p2.db_product_tag_rel = [tag1]
p3.db_product_tag_rel = [tag2]

db.session.commit()
relation

最後我們來對商品查詢看看~

# 查看商品
query = Product.query.filter_by(name='Isacc').first()
print(query.name)

# 輸出> Isacc

當查詢商品時後面只需要加上 db_product_tag_rel,就可以連同查詢 Tag 的表單

# 查看商品標籤
tags = query.db_product_tag_rel

for i in tags:
    print(i.tag_type)

# 輸出> 免運費
# 輸出> 新貨到

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

最後~推薦 Flask 系列文章:

▍關於 Flask 教學系列目錄:

▍關於 Flask 資料庫 SQLAlchemy 文章:

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

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

發佈留言

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