Table
一. 前言
▍什麼是 ORM 架構
簡單來說是直接用 Python 的語法對資料庫進行操作,不需要直接寫 SQL 語法,ORM 背後會自動將 Python 代碼轉換成應對的 SQL 語法,再來進行對資料庫的操作。
關於更多 ORM 相關設定和操作更多內容可參考:
- [Flask教學] Flask-SQLAlchemy 資料庫連線&設定入門 (一)
- [Flask教學] Flask-SQLAlchemy 資料庫操作-ORM篇 (二)
- [Flask教學] Flask-SQLAlchemy -ORM 一對多關聯篇 (三)
二. ORM關聯:多對多
▍定義多對多模型
設定其實很簡單:
Step1. 設定 db.relationship(…) 關係
Step2. 設定 db.Table(‘relations’…),這設定會自動在資料庫建立新的關聯表
Step3. 在 db.Table(‘relations’…) 內設定 db.ForeignKey(…) 關係
就完成囉~
▍舉個簡單的栗子 🌰
首先我們定義了 product、Tag 這兩個模型,一個產品會有多個 Tag,而一個 Tag 也可能會被多個產品,所以多對多的模式就出現了~
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
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:password@IP: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 |
- 在
SQLAlchemy
中設置多對多關聯時,我們並不需要去特別的定義一個 Model 來做中繼,而是透過Table
的方法,來設罝MetaData
,並記錄兩個 Model 的ForeignKey
使用。 - “db.Table(‘relations’…)”的 relations 是待會 SQLAlchemy 會自動生成的關聯表名稱
- ” db.Column(‘tagid_rt’…) “則是設定裡面有的欄位
▍實作操作多對多資料庫
首先將資料庫 product_mul_to_mul 表中存進三筆資料,完成後會看到如下圖:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
# 建立表格 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() |
再來我們新增兩筆 Tag 的資料到 tag_mul_to_mul 表內,完成後會如下圖:
1 2 3 4 5 6 7 |
# 新增商品類型 tag1 = Tag('免運費') tag2 = Tag('新貨到') # commit db.session.add_all([tag1, tag2]) db.session.commit() |
最後我們將各產品與 Tag 互相帶上關係,完成後如下圖:
1 2 3 4 5 6 |
# 將商品新增類型 p1.db_product_tag_rel = [tag1, tag2] p2.db_product_tag_rel = [tag1] p3.db_product_tag_rel = [tag2] db.session.commit() |
最後我們來對商品查詢看看~
1 2 3 4 5 |
# 查看商品 query = Product.query.filter_by(name='Isacc').first() print(query.name) # 輸出> Isacc |
當查詢商品時後面只需要加上 db_product_tag_rel,就可以連同查詢 Tag 的表單
1 2 3 4 5 6 7 8 |
# 查看商品標籤 tags = query.db_product_tag_rel for i in tags: print(i.tag_type) # 輸出> 免運費 # 輸出> 新貨到 |
恭喜你已經完成多對多的新增和查詢囉~
最後~推薦 Flask 系列文章:
▍關於 Flask 教學系列目錄:
▍關於 Flask 資料庫 SQLAlchemy 文章:
- [Flask教學] Flask-SQLAlchemy 資料庫連線&設定入門 (一)
- [Flask教學] Flask-SQLAlchemy 資料庫操作-ORM篇 (二)
- [Flask教學] Flask-SQLAlchemy -ORM 一對多關聯篇 (三)
- [Flask教學] Flask-SQLAlchemy -ORM 多對多關聯篇 (四)
- [Flask教學] Flask-SQLAlchemy 資料庫操作-SQL指令篇 (五)
[Flask教學] Flask-SQLAlchemy -ORM 多對多關聯篇 (四) 結束囉,感謝收看!
有關 Max行銷誌 的最新文章,都會發佈在 Max行銷誌的 Facebook 粉絲專頁,如果想看最新更新,還請您按讚或是追蹤唷!