---
# System prepended metadata

title: 隨手筆記 - Sqlachemy 的三種關聯關係
tags: [' 隨手筆記', Sqlachemy]

---

---
tags: Sqlachemy, 隨手筆記
---

# 隨手筆記 - Sqlachemy 的三種關聯關係

## 撰文動機
第一次使用 Sqlachemy，Model的建立和其他 ORM 差不多，但是關聯的設定需要重新學習一下，以下進行一對多、多對一以及多對多的筆記。

## 關聯關係

### 一對多、多對一

**例子說明:**
以 User 對 Event 的關係為例，一個 User 可以建立多個 Event，一個 Event 只會對應到一個 User，以 User 角度來看 Event 為一對多關係，以 Event 來看就是多對一。

**關聯建立說明:**
[參考](https://stackoverflow.com/questions/51335298/concepts-of-backref-and-back-populate-in-sqlalchemy)

最推雙向關係二 兩張圖皆可以看到其對應關係，相對嚴謹，但必須記得兩邊都要新增或是刪除。

**Code:**
```python
class User(Base):
    __tablename__ = 'user'
    id = Column(Integer, primary_key=True, autoincrement=True)
    # 單向關係
    events = relationship('Event')
    
    # 雙向關係 1.
    events = relationship('Event', back_populates='create_uid')
    
    # 雙向關係 2. 會在 Event 自動建立 create_user 屬性
    events = relationship('Event', backref='create_user')
    

class Event(Base):
    __tablename__ = 'event'
    id = Column(Integer, primary_key=True, autoincrement=True)
    # 單向關係
    create_uid = Column(Integer, ForeignKey('user.id'), nullable=False)

    # 雙向關係 1.
    create_user = relationship('User', back_populates='events')
```


### 多對多

**例子說明:**
以 Product 和 Tag 為例，Product 可以有多個 Tag，一個 Tag 也可以屬於多個 Product，即為多對多的關係。

還是可以跟上面一樣使用 backref 做單邊新增雙向關係。

**Code:**
```python

product_tag_table = Table(
    "association",
    Base.metadata,
    Column("product_id", ForeignKey("product.id"), primary_key=True),
    Column("tag_id", ForeignKey("tag.id"), primary_key=True),
)

class Product(Base):
    __tablename__ = 'product'
    id = Column(Integer, primary_key=True, autoincrement=True)
    name = Column(String, nullable=False)
    
    tags = relationship('Tag', secondary=product_tag_table, 
                        back_populates='products')
    

class Tag(Base):
    __tablename__ = 'tag'
    id = Column(Integer, primary_key=True, autoincrement=True)
    
    products = relationship('Tag', secondary=product_tag_table, 
                        back_populates='tags')
```

## 結語
基本上不會難理解，如果使用上有遇到甚麼問題再持續更新此篇筆記。