Table
一. 前情提要
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 來連線,接下來會再介紹其他的連線方式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
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:
1 |
Postgres:
1 2 |
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql ://username:[email protected]/db' |
SQLite:
1 2 3 4 5 |
#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 被移除使用!
1 2 3 4 |
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 條件寫在裡面。
1 2 3 4 5 6 7 |
app.config['SQLALCHEMY_ENGINE_OPTIONS'] = { "pool_pre_ping": True, "pool_recycle": 300, 'pool_timeout': 900, 'pool_size': 10, 'max_overflow': 5, } |
其中 pool_size
、pool_timeout
… 都蠻好理解的,這邊解釋一下 max_overflow
是指當 connection pool 連線都用光時,最多暫時額外再新增多少的連線數,以上面設定為例子:也就是說當超過 15 connections 時,新的使用者連線是會需要等待,直到超過設置的時間 (pool_timeout),則會連線失敗。
3. 用於 debug 的參數
第一種:SQLALCHEMY_ECHO
此參數預設是 False,當設定成 True 時,對資料庫的任何操作,都會在 console 顯示,如下範例是一個簡單的 ORM query,會將 Raw sql 指令 print 出來:
1 2 3 4 5 6 7 8 9 |
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,指令
如下:
1 |
app.config['SQLALCHEMY_RECORD_QUERIES'] = True |
然後可以在 after_request
後,使用 get_debug_queries 取得 query 的各種資訊,像是查詢時間、raw sql 語法、語法參數… 等。
這部分我有看過有些專案會寫當 query.duration 時間大於多少時,記錄在 log 的應用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
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
此參數用於同時操作多個資料庫時使用,範例寫法如下:
1 2 3 4 |
app.config['SQLALCHEMY_BINDS'] = { 'users': 'mysqldb://localhost/users', 'appmeta': 'sqlite:////path/to/appmeta.db' } |
設置後,建立資料庫寫法如下:
1 2 |
>>> 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,注意:設置後會消耗額外的記憶體。
1 |
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 教學系列】實作 GCP 部署 Flask + Nginx + uWSGI
- 【Flask 教學系列】實作 Flask + GitHub Action CI/CD
- 第一集:實作 Dockerfile + flask 教學 (附GitHub完整程式)
- 第二集:實作 Dockerfile + nginx + ssl + flask 教學 (附GitHub完整程式)
- 第三集:實作 Docker-compose (Flask+Nginx+PostgreSQL)
▍其他 Flask 相關教學:
- Flask 為甚麼需要 WSGI 與 Nginx
- Flask-SQLAlchemy 資料庫連線&設定入門 (一)
- Flask-JWT-Extended 實作
- 實作 Flask CORS
- 實作 Flask CSRF Protection
有關 Max行銷誌的最新文章,都會發佈在 Max 的 Facebook 粉絲專頁,如果想看最新更新,還請您按讚或是追蹤唷!