MiniLake:本地 Databricks API 模擬器,支援 SQL、Delta Lake 與 Spark 任務
MiniLake Is a Local Databricks API Emulator with SQL, Delta Lake and Spark
MiniLake 是一款 MIT 授權的本地 Databricks API 模擬器,允許開發者在無雲帳號、無 API 金鑰的環境下執行 SQL、Delta Lake 與 Spark 任務。
MiniLake 讓開發者在本地無雲帳號即可測試 Databricks API、SQL、Delta Lake 與 Spark,降低 CI 環境成本。
開源 · MIT · Python 3.11+ · Docker
MiniLake 是一個本機的 Databricks API 模擬器,支援 真實 SQL、真實 Delta Lake 以及 真實 Spark 工作執行。指向 databricks-sdk、Databricks CLI、Terraform、Asset Bundles 或 LLM 代理在 http://localhost:8000 — 無帳號、無 API 金鑰、無雲端費用。
$
pip install minilake && minilake --port 8000
PyPI
$
docker run -p 8000:8000 ghcr.io/dmux/minilake:latest
GHCR
然後開啟 http://localhost:8000/ui/ 以使用內建 SQL 工作空間。影像在執行時不會下載任何東西 — 它可以離線運作。
即插即用於
databricks-sdk (Python) Databricks CLI Terraform provider Asset Bundles PySpark + Delta MCP agents
30+模擬 30+ 個 Databricks API 群組,從 Unity Catalog 到 SCIM
67供 LLM 代理使用的 MCP 工具,皆在同一個埠上提供服務
378+測試由真實 Databricks SDK 驅動,而非模擬
$0雲端花費 — 所有執行都在你自己的機器上
你得到的功能
不是模擬伺服器。背後是真實引擎的 Databricks 形狀 API。
虛假端點允許破損的程式碼通過。MiniLake 在 DuckDB 上執行你的 SQL,寫入真實 Delta 檔案,並在容器中執行真實 spark-submit 工作 — 因此本地綠色測試才有意義。
Unity Catalog,真實可用
目錄、模式、表格與卷,皆支援完整 CRUD。每個目錄都是獨立的 DuckDB 資料庫檔案,因此 catalog.schema.table 位址是原生的 — 不是正規表示式重寫。
真實執行
實際執行的 SQL
在真實 DuckDB 上的語句執行:INLINE 與 EXTERNAL_LINKS 方式、JSON_ARRAY / ARROW_STREAM / CSV 格式,以及攜帶真實欄位型別的結果清單。
真實執行
真實 Delta Lake 檔案
EXTERNAL Delta 表格是實際的 Parquet 加上 _delta_log/。INSERT、UPDATE 與 DELETE 透過真實 Spark 工作路由;讀取則經由 DuckDB 的 delta_scan()。
真實 Delta
真正執行的工作
spark_python_task 在同層容器中執行 spark-submit 並回傳實際 stdout。真實 DAG 排程遵循 depends_on 與 run_if,並以獨立分支並行執行。
真實 Spark
Spark 的 Unity Catalog 協定
spark.table("cat.sch.tbl") 透過官方 UCSingleCatalog 聯結器對應 MiniLake — 就是 Spark 與真實工作空間使用的相同協定。
線路相容
內建 SQL 工作空間
在 /ui 的 Athena 風格編輯器:Monaco 具備目錄感知補全、虛擬化結果格、圖表、CSV/JSON 匯出、已儲存查詢、查詢歷史 — 以及嵌入式 JupyterLab。
全功能包
Terraform & Asset Bundles
將 databricks 供應者指向 localhost,並讓 terraform apply 建立真實目錄。每次測試皆已驗證:真實供應者透過 apply、plan 與 destroy 驅動,第二次規劃必須回傳空。databricks bundle deploy 與 bundle run 完整端到端運作 — 工作實際執行。
線路相容
為代理的 MCP 伺服器
67 個工具、8 個資源與 4 個提示在 /mcp — 包含將五次呼叫序列壓縮成一次的複合體,以及一個 SQL 方言資源,阻止代理寫 Spark SQL。
真實執行
為 CI 設計
一個 POST /_minilake/reset 為每個測試提供乾淨工作空間,而無需重新啟動容器。/health、/ready 與 /services 完成控制平面。
測試友善
工作空間、DBFS、檔案、機密
以檔案為基礎的筆記本與檔案儲存,支援分塊上傳。Secrets 為實際 CRUD,其值僅能在工作環境內解析 — 完全如 Databricks。
實際執行
設計上離線隔離
DuckDB 的 delta 擴充與 Delta / Unity Catalog JAR 在編譯時即內建。映像檔執行時不會下載任何東西 — 可用 docker run --network none 驗證。
離線可用
Databricks 風格錯誤
失敗回傳 {"error_code", "message"},SDK 會丟擲正常型別例外。任何超出範圍的專案會回傳響亮的 501 NOT_IMPLEMENTED,而非令人信服的謊言。
線路相容
零程式碼變更
改變主機,即為遷移。
MiniLake 以 Databricks REST API 進行通訊,所有已使用的客戶端仍能正常工作 — 相同的呼叫、相同的回應格式、相同的型別錯誤。
- 任何令牌皆可接受。 無需註冊、無需 PAT、無需 OAuth 舞蹈即可開發。
- 型別往返。
STRING、LONG、DECIMAL(10,2)、ARRAY<T>、MAP與STRUCT對應 DuckDB,並回傳 SDK 的ColumnInfo。 - 實體真相勝出。 宣告的欄位型別若與檔案不符,將失敗,故不相符的專案會被顯示,而非被信任。
- 按需持久化。
MINILAKE_PERSIST=1在關機時快照狀態,啟動時恢復。
quickstart.py
from databricks.sdk import WorkspaceClient
from databricks.sdk.service.catalog import ColumnInfo, TableType
# The only line that differs from production
w = WorkspaceClient(host="http://localhost:8000", token="dev")
w.catalogs.create(name="sales")
w.schemas.create(name="store", catalog_name="sales")
w.tables.create(
name="orders", catalog_name="sales", schema_name="store",
table_type=TableType.MANAGED,
data_source_format="DELTA", storage_location="/data/sales/store/orders",
columns=[
ColumnInfo(name="id", type_text="BIGINT"),
ColumnInfo(name="customer", type_text="STRING"),
ColumnInfo(name="amount", type_text="DECIMAL(10,2)"),
],
)
wh = w.warehouses.create(name="dev", cluster_size="Small")
w.statement_execution.execute_statement(
warehouse_id=wh.id,
statement="INSERT INTO sales.store.orders VALUES (1, 'Ana', 459.90)",
)
result = w.statement_execution.execute_statement(
warehouse_id=wh.id,
statement="SELECT customer, amount FROM sales.store.orders",
)
print(result.result.data_array) # [['Ana', '459.90']] — really stored工作原理
單一程序。單一埠。底層實際引擎。
一個 FastAPI 應用同時提供 Databricks REST 介面、網頁 UI 與 MCP 端點。其後為 DuckDB、實際的 Delta 檔案、以及 Spark 的 Docker。
適用於 LLM 代理
給代理一個他無法破壞的湖屋。
Databricks 工作空間對代理來說是一件尷尬的事:每個有用的動作需四次呼叫,所寫 SQL 的一半使用錯誤的方言,失敗則靜默。MiniLake 的 MCP 伺服器彌補這些缺口 — 當代理出錯時不會產生任何成本。
- setup_fixture()一次冪等呼叫建立目錄+模式+倉庫
- seed_table()表格 + 行,完全符合你所要求的行數
- describe_catalog_tree()一次性描述整個層級,而非數十次呼叫
- run_python_script()階段化、提交至實際 Spark、輪詢、返回 stdout
再加上 8 個資源 — 包含一份 SQL 方言指南,阻止代理在 DuckDB 上撰寫 Spark SQL — 以及 4 個先行載入規則的提示。工具透過 MiniLake 自有的 ASGI 堆疊執行,故代理的錯誤正是 SDK 客戶端會看到的錯誤。
註冊 + 使用
# One line to register it with Claude Code
claude mcp add --transport http minilake http://localhost:8000/mcp
# Then just ask:
# "Use minilake: create a sales catalog with a seeded
# orders table, and tell me the total."
# The agent does this — three calls, no glue code:
# setup_fixture({"catalog": "sales", "schema": "store"})
# seed_table({"full_name": "sales.store.orders", ...})
# run_sql({"statement": "SELECT SUM(amount) FROM sales.store.orders"})
# Enable it on the server side:
MINILAKE_MCP=1 minilake --port 8000覆蓋範圍
模擬內容與其真實度。
以下每一行皆為實際執行或明確標示。任何超出範圍的專案會回傳 501 NOT_IMPLEMENTED,而非偽造成功,生產程式碼將不會收到此類成功。
| 服務 | 狀態 | 其意涵 |
|---|---|---|
| Unity Catalog | 實際 | 目錄、模式、表格、卷、函式 — 每個目錄皆為獨立的 DuckDB 資料庫,支援原生三部位命名 |
| UC 授權 | 未強制 CRUD | 具備實際繼承 — 目錄授權同時套用於其模式與表格 — 但永不檢查許可權 |
| UC 函式 | 實際 | SQL 函式轉為實際 DuckDB 巨集,故 SELECT cat.sch.fn(x) 真正執行計算 — 不是註冊專案 |
| SQL 語句 | 實際 | 在 DuckDB 執行;所有三種格式與兩種處置方式,並附有已型別化的結果清單 |
| EXTERNAL Delta 表格 | 實際 | 真實的 Delta 檔案;寫入透過產生的 Spark 工作進行,讀取則透過 delta_scan() |
| 工作 | 實際 | spark-submit 在兄弟容器中(或子程序回退),真實的 DAG 排程,真實的日誌,單次 runs/submit |
| SQL 資料倉庫 | 實際 | 完整的 CRUD 與生命週期;語句即使在不同狀態下亦會執行,與本地執行相同 |
| 查詢歷史與已儲存查詢 | 實際 | 由伺服器支援,包含失敗案例——這通常是你開啟歷史的原因 |
| 警示 | 實際 | 條件會對真實查詢結果進行評估,故警示會在你的資料上觸發——永遠不會在儲存的常數上 |
| 工作區、DBFS 與檔案 | 實際 | 以檔案為後端的儲存,支援分塊上傳;原始位元組同步是使 bundle deploy 工作的關鍵 |
| 機密 | 實際 | 實際 CRUD;值只能在工作環境變數內解析,永遠無法透過 API |
| 網頁 UI 與筆記本 | 實際 | 在 /ui 的 Athena 風格 SQL 工作區,並於 /jupyter 代理 JupyterLab |
| MCP 伺服器 | 實際 | 選擇啟用 MINILAKE_MCP=1:同一埠上提供 67 個工具、8 個資源、4 個提示 |
| 持久化 | 實際 | MINILAKE_PERSIST=1 於關機時以 JSON 形式快照狀態,並於啟動時還原 |
| 叢集 | 狀態機 | CRUD 加上定時生命週期轉換——刻意不包含 Spark 計算;計算在工作中進行 |
| 政策與例項池 | 未強制 CRUD | 它們會解析並驗證,因此部署時可使用命名為 bundle 的設定——但此處沒有計算供政策約束 |
| 許可權 | 允許全部 CRUD | 實際的建立/讀取/更新,但從未被執行——這是一個單一使用者工具 |
| 工作區管理員 | 未強制 CRUD | Git 憑證、IP 存取清單、初始化指令碼、通知目的地、例項配置檔、工作區設定——terraform apply 在處理過程中會觸及這些 |
| 身份與 SCIM | 未強制 CRUD | 使用者、群組與服務主體,並配合 SCIM 過濾與 PATCH——僅記錄,非憑證;任何 token 仍會被接受 |
| 令牌 | 未強制 CRUD | 值僅回傳一次,正如實際情況——之後不再進行身份驗證 |
舊版 SQL (preview/sql) | 實際 | 在已棄用路徑上的查詢、警示與儀錶板——使用現代儲存的介面卡,兩個表面皆可見同一個物件 |
| DLT、Model Registry、Vector Search、Lakeview、Repos | 未實作 | 返回 501 NOT_IMPLEMENTED — 大聲,避免你誤以為它正在工作 |
直說
MiniLake 不是什麼。
這些是刻意的設計決策,而非待辦清單。MiniLake 針對單一開發者本地執行——非共用、多租戶伺服器。
無驗證
任何 token 都被接受,且只有一個使用者。永遠不要將它暴露於 localhost 之外。
無存取控制
Permissions API 是實際的 CRUD,始終允許所有操作——此處的通過測試並不代表實際工作區的授權。
DuckDB,而非 Spark SQL
語句以 DuckDB 的方言執行。MCP 伺服器提供方言資源,正是為此;檔案中包含翻譯表。
叢集上無 Spark
叢集生命週期為狀態機。真正的 Spark 透過工作,在兄弟容器中執行。
單一程序,無 HA
DuckDB 為單寫入,故同時載入會在鎖上序列化。適合開發與 CI;非部署目標。
MANAGED 表對 Spark 隱形
它們是沒有檔案的 DuckDB 表。當 Spark 必須看到資料時,請使用 EXTERNAL Delta——這種折衷維持了 SQL 的速度。
明確說明邊界才是重點:一個悄悄偽裝自己無法做到的功能的模擬器,還不如一個完全沒有模擬器。

只需一條指令,即可在本機啟動您的 Lakehouse。
免費且採 MIT 授權。無需帳號、API 金鑰,也不會產生雲端費用 — 完成後也不需要從雲端帳戶中解除安裝任何東西。