![]()
一個Python后端項目,95張表,9個業務域,全手寫SQL。作者Vincent D. Warmerdam在博客自曝技術選型清單時,這個數字讓評論區炸了。
更刺激的是他的坦白:有些決定是深思熟慮,有些純粹是"我會這個,得趕緊上線"。兩種理由都成立,但代價在18個月后才陸續到賬。
從JS逃難到Python,他先問"哪個框架不像異鄉"
Warmerdam的背景是JavaScript和TypeScript。多年React前端,Express和Fastify后端。項目需要Python——AI/ML生態的通用語——他需要一個不讓自己水土不服的框架。
FastAPI一眼命中。async/await模型、裝飾器路由、真正起作用的類型提示。"像在用Python寫Fastify",這是他原話。熟悉感不是全部理由,但"撒謊說沒這個因素才是假的"。
技術驗證后來也站住了腳。系統要同時處理:n8n的并發webhook回調、React儀表盤的實時輪詢、PostgreSQL的持久化asyncpg連接。全是異步I/O,而FastAPI是圍繞這個模式生的。Django現在也有異步支持,但"像是后補的,不是設計進去的"。
他故意沒用ORM。所有查詢都是手寫的asyncpg SQL。
95張表橫跨9個域,他想親眼看見什么東西正在撞數據庫。不要魔法,不要N+1驚喜,不要遷移框架生成他沒讀過的SQL。
跳過Django的賬單:3周變3個月,SSH管道里埋著雷
代價來得很快。沒有免費管理后臺,他從零搓了一個React儀表盤,"花了好幾周"。沒有內置遷移系統,他用原始SQL文件管Schema變更,通過SSH管道進Docker里的psql。
這個方案咬過他不止一次。Shell引號在SSH→Docker→psql的鏈條里層層轉義,復雜語句會被啃得面目全非。
插件生態也更薄。Django 20年前就有的東西,FastAPI社區可能還在討論要不要做。
他的結論很干脆:如果你在做帶用戶賬戶、管理后臺、表單的Web應用,"直接用Django"。FastAPI的舒適區是API層——協調服務之間的后端,這正是他的場景。
PostgreSQL的隱藏技能:LISTEN/NOTIFY吃掉了一個消息隊列
數據庫選型沒猶豫。數據深度關聯:交易鏈到銀行賬戶,郵件分類引用消息,知識事實多源強化,調度任務引用代理再引用模型。MongoDB意味著全量反規范化、文檔嵌套、手動一致性。
但PostgreSQL給的超出關系存儲本身。LISTEN/NOTIFY替代了本該用消息隊列做的事:郵件分類完成,觸發器發通知,brain服務通過asyncpg毫秒級捕獲響應。沒有Kafka,沒有RabbitMQ,用的是Postgres內置十幾年的功能。
觸發器函數長這樣:
```sql CREATE OR REPLACE FUNCTION notify_email_classified() RETURNS TRIGGER AS $$ BEGIN PERFORM pg_notify('email_classified', json_build_object( 'email_id', NEW.id, 'classification', NEW.classification )::text); RETURN NEW; END; $$ LANGUAGE plpgsql; ```
這個設計省掉了一套基礎設施。但Warmerdam沒說的是:當通知丟失或重連時,調試LISTEN/NOTIFY的狀態機比看Kafka的offset要痛苦得多。
那篇博客沒寫完的部分:運氣成分到底占幾成?
Warmerdam在結尾留了個口子。他承認自己"賭對過,也幸運過",但具體哪些屬于哪類,讀者得自己從95張表的Schema變更日志里翻。
一個細節被埋在評論區:那個React儀表盤至今還有3個已知bug,因為"寫SQL比調useEffect爽多了",優先級一直被壓。
如果你也在Python生態里做技術選型,他的清單里哪一條最讓你意外——是"全手寫SQL"的偏執,還是"用熟悉工具換速度"的誠實?
特別聲明:以上內容(如有圖片或視頻亦包括在內)為自媒體平臺“網易號”用戶上傳并發布,本平臺僅提供信息存儲服務。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.