第十屆鐵人賽 flask-restful DAY27-搞懂Flask-SQLAlchemy關聯資料庫

Flask-SQLAlchemy關聯資料庫

相信對於SQL資料庫有些認識的讀者們都知道資料庫可以設定關聯,然而Flask-SQLAlchemy如何處理這樣子的關聯呢,又或者如何設定兩個Table的資料是有關連的呢,這就是今日教授內容的重點

為何要設定關聯

在前幾日筆者教授大家如何透過設定UserModel來設定使用者資料,並定義了使用者資料的內容為何,再來透過Flask-Mirgate來產生資料庫的結構,以及若是新增欄位該如何處置。但是以上的內容都是僅有一個Table的內容,而現實生活中的資料庫並不是這麼單純的,雖然單純的資料庫透過程式的設計是可以靈活的存取資料,但是在資料的維護及更新上相較之下就變得複雜了。

例如今天有個post的Table紀載著使用者的貼文內容,當然會有個id來表示是哪個使用者發表貼文,甚至於有個id來表示那些使用者對此貼文發表感想,當然讀者們可以分開來存取,但是如此對資料庫的效能上是一個考驗,當然最恰當的做法是可以一個查詢就可以取的資料,但是怎麼做呢?這就是今天要介紹的關聯。

如何設定關聯

經過上述的例子希望讀者們能瞭解為何使用資料庫的關聯,而接下來就透過上述的例子來說明怎麼在Flask-SQLAlchemy設定關聯,首先我們先定義post的Model

class PostModel(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(50), nullable=False)
    content = db.Column(db.String(50), nullable=False)
    poster_id = db.Column(db.Integer, db.ForeignKey('user.id'),
        nullable=False)

透過poster_id我們可以將PostModel與UserModel關聯起來,但是如何在查詢使用者資料時將先關的貼文資料給一併查詢出來呢,這部分接下來說明。

如何設定查詢關聯

這部分說明如何在查詢使用者資料時將先關的貼文資料給一併查詢出來,所以我們繼續修改UserModel:

class UserModel(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(80), unique=True, nullable=False)
    email = db.Column(db.String(120), unique=True, nullable=False)
    password = db.Column(db.String(120))
    posts = db.relationship('PostModel', backref='user', lazy=True)

透過上述的程式即可將使用者與貼文兩個資料關聯起來,而且在查詢使用者時取得貼文的資訊,反過來當取得貼文時也可以取的貼此文的作者的資訊。

設定flask-marshmallow

依據上述的做法可以完成資料庫以及flask-SQLAlchemy的關聯,但是要回傳給client端各位讀者應該只會看到使用者資料,這問題出在哪裡呢?因為我們回傳給客戶端的資料是透過flask-marshmallow來dump成json的格式,所以接下來要修改UserSchema來處理這問題,請看以下修改:

from common.ma import ma
from marshmallow import validate
from models.user import UserModel
from models.schema.post import PostSchema


class UserSchema(ma.Schema):
    class Mate:
        model = UserModel
    id = ma.Int()
    name = ma.Str()
    email = ma.Email(required=True)
    password = ma.Str(required=True, validate=[
                      validate.Length(min=6, max=36)],)
    posts = ma.List(ma.Nested(PostSchema))

這裡我們多加一個PostSchema來定義解析以及回傳給client端的貼文資料,因為使用者資料是一對多的結構,也就是一個使用者有多張貼文,所以使用者會有一個posts的屬性,他是一個list的PostSchema,所以我們使用ma.List以及ma.Nested(PostSchema)來解析UserModel的posts屬性,如此就能在返回client端正常dump UserModel的posts內容。

小結

透過flask-SQLAlchemy可以將開發變得更便利,不用寫過多的程式碼就可以將兩個Table給關聯起來並互相取得。在取得資料變得更便利的狀況下,如何驗證使用者是否有資格取的資料就顯得重要了,再來今日的課程關於使用者id的傳輸是透過post參數來傳輸,如果說入錯了會怎麼樣呢,是不是就歸屬到別人的貼文內了。所以明天要在教授大家如何驗證使用者是否有資格調用此api,敬請期待。

發表迴響

你的電子郵件位址並不會被公開。 必要欄位標記為 *