上線三天資料就不見了——為什麼 AI 生成的專案這麼愛用 SQLite,以及什麼時候該換成 PostgreSQL

上線順利、三天後客戶打來說「資料都不見了」
您的系統上週五終於部署成功,週末測試一切正常,週一開始接真實訂單。週三早上接到客戶電話:「昨天的訂單怎麼都查不到?」您登入後台一看,資料庫是空的——不只昨天,連上週五測試時建的那幾筆示範資料也消失了。
問題不是駭客、不是程式碼有 bug,而是 AI 工具幫您選的資料庫方案:SQLite 資料庫檔案存在專案資料夾裡,而您用的雲端主機每次重新部署或重啟容器時,會把整個專案資料夾清空重建。<cite index="2-1,2-10">在容器化或短暫性部署環境(像 Fly.io、Railway)上,如果 SQLite 用了相對路徑的檔名,會在每次部署或重啟時默默建立一個新的空白資料庫</cite>。
這不是個案。這是 2026 年「AI 幫我寫完、我自己上線」最常踩的坑之一。
為什麼 AI 工具這麼愛用 SQLite——以及這個選擇在本機跑沒問題
ChatGPT、Cursor、Bolt、Lovable 這類 AI 程式碼生成工具,在您沒有特別指定資料庫時,常常預設幫您產生 SQLite 設定。原因很簡單:<cite index="11-4,11-5,11-6">SQLite 的部署就是複製一個檔案,不需要安裝、不需要設定、不需要管理背景服務,您的資料庫就是一個可以用 cp 指令備份、用 sqlite3 指令檢查的普通檔案</cite>。
在本機開發時,這個選擇完全合理。專案資料夾不會被清空、重啟電腦資料也還在,而且不用額外裝 PostgreSQL 或 MySQL 伺服器。但當您把這套程式碼部署到雲端主機、容器平台、或任何「重新部署會重置檔案系統」的環境時,問題就來了。
<cite index="5-1,5-2">Heroku 的 Cedar stack 有個短暫性檔案系統——您可以寫入、可以讀取,但內容會定期清空</cite>。Railway、Render、Fly.io、甚至用 Docker 自己架的環境,只要沒有明確掛載持久化儲存空間(persistent volume),<cite index="20-3">當容器停止或被移除時,寫入容器內部的任何資料都會消失</cite>。
什麼情況 SQLite 可以接受、什麼時候必須換成 PostgreSQL
可以繼續用 SQLite 的情境
如果您的系統符合以下條件,SQLite 不是妥協方案,而是正確的架構選擇:
- 單一伺服器、不需要橫向擴展:<cite index="6-5,6-6,6-7,6-8">SQLite 一次只允許一個寫入者——不是每張表一個,而是整個資料庫一個。這個特性決定了您的部署架構:多個 process 不會增加寫入容量,只會增加對同一個鎖的競爭</cite>。
- 讀取為主的工作負載:內部報表工具、唯讀 API、內容管理後台,這些場景 SQLite 表現優異。
- 您願意正確設定持久化儲存:在 Docker Compose 裡明確宣告 volume、在雲端平台上掛載 persistent disk,<cite index="7-12,7-13">容器部署需要為 .db 檔案路徑準備一個持久化 volume,短暫性檔案系統會在重啟時遺失資料</cite>。
參考我們的 本機跑得起來、上線就壞掉 一文,了解部署環境與開發環境的關鍵差異。
該換成 PostgreSQL 的時機
以下情況 SQLite 會成為系統成長的天花板,建議從一開始就用 PostgreSQL:
- 多地區部署、需要多個寫入節點:電商在台北和高雄各有一台伺服器同時接單。
- 高並發寫入:即時聊天室、IoT 裝置同時回傳數據、大量訂單同時湧入。
- 需要進階 SQL 功能:全文搜尋(PostgreSQL 內建
tsvector)、JSON 欄位查詢、視窗函數。 - 您的雲端平台不提供可靠的 persistent volume:某些 serverless 平台根本不支援檔案持久化,這時連正確設定 SQLite 的機會都沒有。
如果您已經上線、現在才發現用錯資料庫,可以參考 軟體交接清單,確保在遷移過程中沒有遺漏關鍵步驟。
如果您已經在用 SQLite,現在該檢查什麼
- 確認資料檔案位置:在專案裡搜尋
.sqlite、.db這類檔案,或找DATABASE_URL這個環境變數。如果看到相對路徑(像./data/app.db)而您的部署環境是容器,資料很可能不會保留。 - 檢查 volume 設定:如果用 Docker Compose,確認
volumes:區段有明確宣告資料庫檔案所在的目錄。<cite index="21-2">-v pgdata:/var/lib/postgresql 這個語法告訴 Docker:如果名為 pgdata 的 volume 存在就掛載它,否則就建立一個</cite>。 - 測試一次完整的重新部署:在測試環境建幾筆資料、觸發一次完整重新部署(不只是重啟、而是整個容器砍掉重建),然後確認資料還在。這是唯一能驗證設定正確的方法。
關於備份與還原演練的重要性,請參考 廠商說「有備份」,但您試過還原嗎?
遷移到 PostgreSQL 該怎麼做
如果評估後決定要換,步驟比您想像的單純:
- 在雲端平台開一個 PostgreSQL 資料庫:Heroku、Railway、Render、Supabase、Neon.tech 都提供 managed PostgreSQL,不用自己管伺服器。
- 調整連線設定:把
DATABASE_URL從 SQLite 的sqlite:///app.db改成 PostgreSQL 的postgresql://user:pass@host:5432/dbname。多數 ORM(像 Prisma、Django ORM、SQLAlchemy)會自動處理語法差異。 - 匯出舊資料、匯入新資料庫:用
.dump指令從 SQLite 匯出 SQL、再用psql或資料庫管理工具匯入 PostgreSQL。注意日期時間格式與自動遞增欄位可能需要微調。 - 在測試環境完整驗證:不只是「能不能連上」,而是跑一輪完整的使用者流程——註冊、登入、新增資料、查詢、更新——確認所有功能都正常。
如果這些步驟看起來很複雜、或您不確定現有系統是否安全可以動,這正是 AI 上線專家的免費健診能幫您的:我們會檢查您手上的專案、告訴您哪些地方有風險、以及最省力的上線路徑是什麼。
您手上有個做到一半的系統、不確定資料庫設定是否正確? 預約一次免費的程式碼健診,我們會檢查您的專案、指出潛在的資料遺失風險,讓您在真正上線前把問題解決。