前情提要
有使用過 Django 製作專案會知道,當我們執行 python manage.py runserver 指令時,Django 會自動生成一個 db.sqlite3 的 SQLite 資料庫檔案,並根據這個資料庫進行模型 Model 的讀取與操作。
(這個 db.sqlite3 是 Django 自動生成給我們的)
Django 是如何進行分工的?
延伸閱讀:〈日常 Python:MVC (Model-View-Controller) 架構是什麼?〉
為什麼 Django 預設的資料庫是 db.sqlite3 呢?
我們可以在 Django 專案中的 settings.py 中找到這一段程式碼:
# Database
# https://docs.djangoproject.com/en/5.0/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
}
如果我們逐步剖析這段程式碼的語意,可以理解為:
* 針對 Django 的資料庫(DATABASES
)進行設置
* 將 Djanog 預設(default
)的資料庫(ENGINE
)引擎設置為 SQLites(django.db.backends.sqlite3
)
* 資料庫檔案生成的路徑與名稱(NAME
)為 BASE_DIR / ‘db.sqlite3’
SQLite 感覺已經很好用了,有需要換其他資料庫引擎嗎?
想像 SQLite 是便條紙,適合我們紀錄簡單的事情,不過通常一張便條紙只會紀錄一個人的事情,如果許多人共用一張便條紙,會讓紙上的內容變得亂七八糟。
而 PostgreSQL、MySQL 這類的更進階的資料庫,則像是一本筆記本,有需多頁數可以紀錄不同的事項,也可以分配不同的頁數範圍供許多人共同紀錄、撰寫內容。
假設我們的專案需要處理許多數據內容,同時也會有多位使用者訪問、操作我們的資料庫,那在這類情境下,SQLite 可能會不堪負荷,而 PostgreSQL、MySQL 或是其他的資料庫引擎,會是更適合的選擇。
(大象 (PostgreSQL) vs 海豚 (MySQL))
所以在本篇文章中,會引領各位一步步將 Django 的預設資料庫引擎,由原本的 SQLite 改為 PostgreSQL,至於 PostgreSQL 與 MySQL 的優劣,則不在本文的討論之中。
|接下來的設定流程,是假定使用者為 MacOS 作業系統,並使用 Poetry 作為 Python 專案管理工具,Windows 使用者可能會遇到一些問題,需要另覓他法解決,先說聲抱歉了!
將 Django 預設資料庫引擎改為 PostgreSQL
|本文流程的前置條件:使用 MacOS 作業系統、使用 Homebrew 套件管理工具、使用 Poetry 管理 Python 套件與虛擬環境
根據 Django 的官方文件,除了提供 PostgreSQL 的配置方法,同時也提供 MariaDB、MySQL、Oracle、SQLite 等其他幾種資料庫的配置,如果有需要配置 MySQL 的相關方法,也可以在這邊得到解答。
開始之前:閱讀官方文件是很重要的事
有些人可能會直接詢問 GPT:「如果我想將 Django 資料庫改為 PostgreSQL,該怎麼做?」這時 GPT 可能會請你安裝一個名為 psycopg2 的套件,這個套件主要是用來處理 Django 與 PostgreSQL 之間的所有互動,讓我們的 Django 專案可以進行 SQL 查詢、管理資料庫中的資料、建立 table 等。
不疑有他,我們跟隨著 GPT 的指令——poetry add psycopg2,然後一步步邁向我們想要的結果,畢竟看文件這麼累,誰要看?
(GPT 是對的!)
然而,如果願意多花個幾分鐘,稍微自己查一下文件,確認一下 GPT 給的答案是否正確,便會在 Django 官方文件中發現這段內容:
(翻譯年糕:psycopg2 很有可能在未來被棄用或是移除。)
根據 Django 的文件內容,Django 支援 PostgreSQL 13 以上的版本,並且建議使用 psycopg 3.1.8 以上的版本作為驅動套件。
|注意:psycopg2 跟 psycopg 是兩個不同的套件!
所以從結果來說,雖然安裝 psycopg2 或是 psycopg 都可以讓我們成功配置 PostgreSQL,但文件上是更推薦 psycopg。
步驟一:安裝 PostgreSQL
由於本文使用 Homebrew 作為套件管理系統,所以我們可以使用指令 brew install postgresql@16
,進行安裝 PostgreSQL 16。
|注意:如果使用 brew install postgresql
而沒有指定版本號,Homebrew 可能會預設安裝 PostgreSQL 14。
待 Homebrew 安裝好 PostgreSQL 16 後,我們可以使用 brew services list 確認目前 PostgreSQL 16 的運行狀態,一般來說會看到 Status 為 none,代表此時 PostgreSQL 並未運行。
(此時可以看見 PostgresSQL 16 尚未運行)
接下來我們可以使用指令 brew services start postgresql@16
啟動 PostgreSQL,並使用 brew services list
檢查 PostgreSQL 的運行狀態,如果 Status 為綠字的 started 則代表正常運作。
(綠字 started 代表正常運作中)
|萬一 Status 出現紅字的 Error,那就代表有問題,需要慢慢查找發生的原因並進行排除了⋯⋯(過來人的痛)
步驟二:安裝 psycopg
由於 Django 與 PostgreSQL 需要透過 psycopg 進行串接,所以我們需要使用指令 pip install psycopg[binary]
安裝 psycopg,不過本文稍早有說過,我們主要使用 Poetry 來管理 Python 套件與虛擬環境,所以指令需要改為 poetry add “psycopg[binary]”
來新增安裝 psycopg,這邊要特別注意,由於 binary 前後有中括號,所以一定要加上引號 ””
才能進行安裝,不然會跳出 zsh: no matches found: psycopg[binary]
的錯誤。
|冷知識:Psycopg 實際上就是 Psycopg 3,但安裝套件名稱是 psycopg 而不是 psycopg3,如果使用 pip install psycopg3
會無法安裝套件喔!
步驟三:調整 Django 專案 settings.py 的配置
如同文章最開始所說的,Django 裡 settings.py 本來預設為 SQLite,如果要調整成 PostgreSQL,這時候又要回去閱讀 Django 官方文件:
(Django 提供的 PostgreSQL 設置方法)
可以看到在 Django 的 settings.py 中,需要改成以下設定:
DATABASES = {
"default": {
"ENGINE": "django.db.backends.postgresql",
"OPTIONS": {
"service": "my_service",
"passfile": ".my_pgpass",
}
}
}
讓我們細細解析:
“ENGINE”: “django.db.backends.postgresql”
:將資料庫引擎改為 PostgreSQL“service”: “my_service”
:指定my_service
為 PostgresSQL 的服務內容(service),用於簡化 PostgreSQL 的簡化配置“passfile”: “.my_pgpass”
:指定 .my_pgpass 為 PostgreSQL 的密碼文件,這個文件存放數據庫的密碼,讓應用程序在連接數據庫時無需在代碼中硬編碼密碼。 以上的文件內容,看起來有點錯綜複雜,所以我們直接走一條輕鬆的道路,可以將 settings.py 修改為:
DATABASES = {
"default": {
"ENGINE": "django.db.backends.postgresql",
"NAME": "database_name", # 填入 database 的名稱
"USER": "user_name", # 填入 PostgreSQL 的 user 名稱
"PASSWORD": "user_password", # 填入 PostgreSQL 的 password
"HOST": "localhost", # 預設為 localhost
"PORT": "5432", # 預設為 5432
}
}
不過雖然這樣的好處是方便配置,也相對淺顯易懂,然而對比於 Django 官方推薦的方式,因為資料庫的密碼直接寫在 settings.py,其實是沒有什麼安全性的,不過現在我們就稍稍偷懶一下吧。
| 之後有機會再針對這塊寫一篇 Django 官方推薦的做法。
這邊我們先把這 settings.py 設定成這樣:
DATABASES = {
"default": {
"ENGINE": "django.db.backends.postgresql",
"NAME": "my_database", # database 的名稱設為 my_database
"USER": "postgres", # PostgreSQL 的 user 名稱設為 postgres
"PASSWORD": "postgres", # PostgreSQL 的 password 設為 postgres
"HOST": "localhost",
"PORT": "5432",
}
}
步驟四:設定 PostgreSQL
此時如果我們先試試看使用 python manage.py runserver 嘗試啟動專案,可能會出現錯誤:
(紅框處指出:「連接錯誤,database “my_database” 不存在」。)
根據錯誤提示,此時我們的 PostgreSQL 裡面尚未存在名為 mydatabase 的資料庫(database),所以我們應該在 PostgreSQL 中,使用 postgres 這個使用者創建一個 mydatabase 的資料庫。
|如果你的終端機出現的是類似 user “postgres” does not exist
的錯誤訊息,代表 PostgreSQL 尚未存在 postgres 這個預設的使用者。
|我們可以在終端機使用指令 createuser -s postgres
在 PostgreSQL 中創建一個名為 postgres 的超級使用者。
這時我們可以使用指令 psql -U postgres
進入到 PostgreSQL Interactive Terminal(交互式命令行工具),並操作預設的 postgres 資料庫。
(如果成功進入到 psql,畫面應該會長這樣)
在 psql 裡面,我們可以使用 SQL 語法或是 psql 專屬命令進行資料庫的管理與操作,以剛剛的錯誤訊息為例,如果我們需要創造一個名為 mydatabase 的資料庫,我們需要輸入指令 `CREATE DATABASE mydatabase;,成功創建後,會跳出
CREATE DATABASE` 的訊息知會。
(創建名為 my_database 的 DATABASE,記得最後要加分號!)
我們也可以使用 psql 命令 \l
來列出 PostgreSQL 裡所有的資料庫與其詳細資料:
(可以看到 my_database 的擁有者(Owner)為 postgres)
|如果我們想要跳出 psql,可以使用 \q
跳出 PostgreSQL Interactive Terminal。
步驟五:確認能否成功啟動 Django 專案
此時當我們回到終端機再重新使用 1python manage.py runserver1,應該就能看到 Django 專案成功執行的相關訊息了。
(此時 Django 紅字提示:「有 18 個 migrations 尚未被應用。」)
步驟六:應用 migrations 並確認資料庫結構改變
稍早有說到我們可以使用 psql -U postgres
的指令,進入到 PostgreSQL Interactive Terminal(交互式命令行工具),並操作預設的 postgres 資料庫。
由於此時我們也已經有了 mydatabase 這個資料庫,所以我們可以使用 `psql -U postgres -d mydatabase`,指定使用 postgres 使用者並連接讀取 my_database 這個資料庫。
(成功連接後,紅框處會顯示此時連接的資料庫名稱)
|冷知識:在執行 psql -U postgres
這個指令時,實際上是在執行 psql -U postgres -d postgres
,只是因為 User 與 Database 剛好都是同名的 postgres,所以可以省略 -d postgres
這段指令。
我們可以在 psql 中使用 \dt
查看資料庫中的所有資料表(tables),不過因為我們尚未應用 migrations 至 my_database 資料庫裡,所以會顯示 Did not find any relations.
。
(\dt 的完整意思是:describe tables)
當我們執行 python manage.py migrate 應用 migrations 至資料庫後,再使用 \dt 查看 my_database 中的資料表時,就可以看到資料庫裡面成功出現應用 migrations 後的 tables 了。
(這些 tables 是 Django 專案預設的 tables)
小結
透過上述步驟,我們成功將 Django 預設的 SQLite 資料庫引擎替換為 PostgreSQL,而這樣的轉換不僅能夠更好地支持多使用者、高併發的應用場景,還讓我們的專案具備了更高的擴展性與穩定性。
之後有空再繼續寫一些有關 psql 相關的指令操作,以及如何真正按照 Django 官方文件來配置 PostgreSQL 作為指定的資料庫引擎。