04 Python Flask 教學10 所有文章

[Flask教學] Flask-SQLAlchemy 參數設置(進階)

Flask SQLAlchemy 參數設置

一. 前情提要

1.本篇最後更新於 2020/10/16,如有部分內容失效,麻煩請告知,我會立即更新!

2.作者環境配置:

  • Flask-SQLAlchemy == 2.4.4
  • Python == 3.7.7
  • Flask == 1.1.2

3.參考官方原文進行編譯: Configuration — Flask-SQLAlchemy Documentation (2.x)

二. 先建立簡單的 Flask 設置

底下是一個最基礎的 Flask 搭配 Flask-sqlalchemy 套件的參數設置,使用 app.config 來載入 Flask-sqlalchemy 的參數,設定上最少會需要放置 db 的連線位置,這個簡單的案例是使用 sqlite 來連線,接下來會再介紹其他的連線方式:

from flask import Flask
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)

app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////absolute/path/to/foo.db'

db = SQLAlchemy(app)

@app.route('/')
def demo():
    return 'Hello Flask'

if __name__ == "__main__":
    app.run(debug=True)

三. 實用的 Flask-SQLAlchemy 參數設定

接下來會介紹三種很常會碰到的參數設定,分別是「資料庫連線參數」、「資料庫細節設定參數」和「用於 debug 的參數」

1. 資料庫連線參數

這邊僅列出筆者常用到的「MySQL」、「Postgres」和「SQLite」,如果想看其他資料庫連線可以參考:Connection URI Format

MySQL:

app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://username:[email protected]/db'

Postgres:

app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql
://username:[email protected]/db'

SQLite:

#Unix/Mac (note the four leading slashes)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////absolute/path/to/foo.db'

#Windows (note 3 leading forward slashes and backslash escapes)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///C:\\absolute\\path\\to\\foo.db'

2. 資料庫細節設定參數

注意:以下這些參數寫法將會在 v3.0 被移除使用!

app.config['SQLALCHEMY_POOL_RECYCLE'] = 90
app.config['SQLALCHEMY_POOL_TIMEOUT'] = 900
app.config['SQLALCHEMY_POOL_SIZE'] = 10
app.config['SQLALCHEMY_MAX_OVERFLOW'] = 5

建議修改成如下:v2.4 開始新增 SQLALCHEMY_ENGINE_OPTIONS,可以將 ENGINE 條件寫在裡面。

app.config['SQLALCHEMY_ENGINE_OPTIONS'] = {
    "pool_pre_ping": True,
    "pool_recycle": 300,
    'pool_timeout': 900,
    'pool_size': 10,
    'max_overflow': 5,
}

其中 pool_sizepool_timeout … 都蠻好理解的,這邊解釋一下 max_overflow 是指當 connection pool 連線都用光時,最多暫時額外再新增多少的連線數,以上面設定為例子:也就是說當超過 15 connections 時,新的使用者連線是會需要等待,直到超過設置的時間 (pool_timeout),則會連線失敗。

3. 用於 debug 的參數

第一種:SQLALCHEMY_ECHO

此參數預設是 False,當設定成 True 時,對資料庫的任何操作,都會在 console 顯示,如下範例是一個簡單的 ORM query,會將 Raw sql 指令 print 出來:

app.config['SQLALCHEMY_ECHO'] = True


db.session.query(Article).all()
>>> output:
2020-10-06 13:43:04,816 INFO sqlalchemy.engine.base.Engine {'param_1': 113}
2020-10-06 13:43:04,831 INFO sqlalchemy.engine.base.Engine SELECT count(*) AS count_1 
FROM (SELECT article.id AS article_id, article.created_at AS article_created_at, article.updated_at AS article_updated_at, article.`textTitle` AS `article_textTitle`, article.`textDescriptionShort` AS `article_textDescriptionShort`, article.top AS article_top, article.thumbnail AS article_thumbnail, article.`testingResult` AS `article_testingResult`, article.aid AS article_aid 
FROM article) AS anon_1
第二種:SQLALCHEMY_RECORD_QUERIES

還有另一種是將 SQLALCHEMY_RECORD_QUERIES 設為 True,指令
如下:

app.config['SQLALCHEMY_RECORD_QUERIES'] = True

然後可以在 after_request 後,使用 get_debug_queries 取得 query 的各種資訊,像是查詢時間、raw sql 語法、語法參數… 等。

這部分我有看過有些專案會寫當 query.duration 時間大於多少時,記錄在 log 的應用。

from flask_sqlalchemy import get_debug_queries

@app.after_request
def after_request(reponse):
    for query in get_debug_queries():
        print(query.statement) # SQL 查詢語法
        print(query.parameters) # SQL 查詢語法的參數
        print(query.duration) # 查詢花費的時間
        print(query.context) # 請求的來源上下文
    return reponse


@app.route('/test')
def test():
    p = Person.query.filter_by(username='Max').first()
    return 'ok'

四. 較少使用的配置參數

1. SQLALCHEMY_BINDS

此參數用於同時操作多個資料庫時使用,範例寫法如下:

app.config['SQLALCHEMY_BINDS'] = {
    'users': 'mysqldb://localhost/users',
    'appmeta': 'sqlite:////path/to/appmeta.db'
}

設置後,建立資料庫寫法如下:

>>> db.create_all(bind=['users'])
>>> db.create_all(bind='appmeta')

2. SQLALCHEMY_TRACK_MODIFICATIONS

Signal (信號) 是 Flask-SQLAlchemy 中較少人使用的功能,官方文件的說明也超少!甚至在 Flask-SQLAlchemy 官方文件中 3.x 的版本 提到,如果要使用 Signal event 建議直接使用 SQLALchemy (附上原文 In most cases, you’ll probably be better served by using SQLAlchemy events directly.)。

那如果有需要使用到 Flask 內建的 Signalling Support 的話,會需要將 SQLALCHEMY_TRACK_MODIFICATIONS 設置成 True,注意:設置後會消耗額外的記憶體。

app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True

而有關於 Flask Signal 功能可以參考此篇有更詳細的說明:说说 Flask 中的 Signal – SHUHARI 的博客

以及一個實際使用案例,可以參考這篇 Stack Overflow 有人有說明:python – SQLALCHEMY: how to use @events.listens_for in flask_sqlalchemy-SQLalchemy – Stack Overflow

最後~

▍回顧本篇介紹 Flask-Sqlalchemy 的參數介紹如下:

  • SQLALCHEMY_DATABASE_URI
  • SQLALCHEMY_ENGINE_OPTIONS
  • SQLALCHEMY_ECHO
  • SQLALCHEMY_RECORD_QUERIES
  • SQLALCHEMY_BINDS
  • SQLALCHEMY_TRACK_MODIFICATIONS

更多 Flask 教學相關閱讀:

▍關於 Flask 教學系列目錄:

▍關於 Flask 部署相關文章:

▍其他 Flask 相關教學:

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

發佈留言

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