Azure Django Python

[Django] 事求人開放資料網站更新雜記

人事行政總處事求人開放資料版網站是我多年前的一個 side project,當時是把整個網站放在 AWS EC2 上,底層的 infra 如 Apache web server 以及 Django 的 WSGI 設定等都是自己來,承蒙大家的關照,多年來網站的 DAU (每日使用者) 一直都滿穩定的。去年剛好有個空檔,就把我一直想調整的留言顯示介面改好了,同時也順便升級網站後端,並且搬到 Azure PaaS 上。總結來說這次的更新有:

  • 把 Django 版本從 1.8 換到 4.2 LTS
  • 把網站從 AWS EC2 (IaaS, 自架 web server),搬到 Azure Web App (PaaS);好處是直接支援 HTTPS 以及自訂網域,部署也相對容易
  • 把資料庫從 SQLite 移到 Azure MySQL

以下是網站升版過程的一些技術筆記。網站本身也是開源的,對程式碼有興趣的可以直接參考 GitHub Repo

Django 版本從 1.8 換到 4.2 LTS

這部份並不困難,就是把專案程式碼在本機直接改用 Django 4.2 版執行,過程中會看到各式不相容或過期的程式碼錯誤/警告,把它們都改掉,直到網站可以成功在本機跑起來即可。

改用 Azure Web App

微軟這篇手把手的教學說明了如何把 Django 網站部署到 Azure Web App 上。相對於部署在自己的主機上,特別要注意的地方有:

  • 需額外安裝 whitenoise 套件
  • 在 Django 預設的 settings.py 以外,需另外創建一個設定檔 azure.py ,並且
    • 在 MIDDLEWARE 變數內新增 whitenoise.middleware.WhiteNoiseMiddleware
    • 設定靜態檔案儲存位置:STATICFILES_STORAGE = ('whitenoise.storage.CompressedStaticFilesStorage')
    • 對於 ALLOWED_HOSTSCSRF_TRUSTED_ORIGINS 變數,至少要加上 os.environ['WEBSITE_HOSTNAME'] ;如果你還有自訂網域,也要記得加上

把網站移到 Azure Web App 上後,自動部署 (with GitHub Action) 與自訂網域等設定就變得簡單許多,不需要再煩惱網站主機的各項設定 (如 http.conf 或如何支援 HTTPS 等)

資料庫從 SQLite 移到 MySQL

這部份是花最多時間的,這篇文章滿清楚地說明了資料轉移的四個步驟:

  1. 把資料用 python manage.py dumpdata dump 出來
  2. 建立 MySQL 資料庫及資料表
  3. 更改 Django 設定檔中 DATABASES 變數的值,改指向 MySQL engine
  4. 把第一步的資料用 python manage.py loaddata 匯入新的資料表中

我的資料內容包含了 4 bytes 的 UTF-8 內容及一些亂碼,這些不符合資料欄位定義的內容以前都被 SqLite 資料庫默默的吞下去且儲存起來,但在 MySQL 中會報錯,資料匯入過程中會看到類似以下的錯誤訊息:

(1366, "Incorrect string value: '\\\\xF0\\\\x9F\\\\x98\\\\x80\\\\xF0\\\\x9F...' for column 'name' at row 1")

這是因為 MySQL 的 UTF-8 只允許 3 個位元組的資料,要修正這個錯誤,必須在一開始創造資料庫及資料表的時候,就使用 utf8mb4 的 Character set 以及 utf8mb4_general_ci 的 Collation. 同時在 Django 的 DATABASES 變數中要多加一個 option:

'OPTIONS': {'charset': 'utf8mb4'}

更多細節可參考這篇這篇 post

最後,在資料轉移時,我並不需要 Django admin 的資料,而只需要我的 App 資料。使用如下指令就可以只 dump 特定 App 或 Model 的資料 (細節可見這篇問答)

manage.py dumpdata myapp1 myapp2.my_model

網站是開源的,對更多細節有興趣的可以到 GitHub 上看程式碼:

https://github.com/jwlin/dgpa-job-site