返回文章列表

DuckDB與ApacheArrow和Polars互操作性

本文探討 DuckDB 與 Apache Arrow 和 Polars 的互操作性,如何在 Python 環境中將 DuckDB 表格轉換為 Polars DataFrame 和 Apache Arrow 表格,並使用 pyarrow 進行資料操作。此外,文章還介紹了 MotherDuck,一個根據 DuckDB

資料函式庫 資料分析

DuckDB 與 Apache Arrow 和 Polars 的整合,為資料科學家提供了更有效率的資料處理流程。藉由 Arrow 的欄位記憶體格式,DuckDB 可以與 Polars 和 pandas 等函式庫無縫交換資料,減少序列化和反序列化的成本。這對於需要在不同工具之間切換的分析工作流程至關重要。Polars 作為新興的資料分析工具,其高效能和記憶體效率,結合 DuckDB 的資料函式庫功能,為處理大型資料集提供了強大的解決方案。

在 Python 中,使用 con.table().pl() 可以輕鬆地將 DuckDB 表格轉換為 Polars DataFrame,並選取所需的欄位。同樣地,使用 to_arrow_table() 可以將 DuckDB 表格轉換為 Arrow 表格,以便使用 Arrow 的 Python API 進行更進階的資料操作,例如篩選和選取特定欄位。這些功能讓資料科學家可以更彈性地運用不同的工具,並根據需求選擇最適合的資料格式。

6.5 與 Apache Arrow 和 Polars 的互操作性

在資料分析領域中,一個健全的系統必須具備良好的適應性。能夠在不同格式或平台之間無縫轉換,對於高效的資料操作、儲存和視覺化至關重要。DuckDB 的優勢之一是其能夠與多種資料格式進行互動,無論是在記憶體中還是在外部。這種互操作性在與其他工具整合或輸出結果進行進一步分析時尤其寶貴。

目前,資料科學生態系統中充滿了各種工具,但不斷有新的函式庫出現,提供更好的效能或獨特的功能。其中一個新興的明星是 Polars。儘管 pandas 多年來一直是 Python 資料分析的實際標準,但 Polars 提供了令人興奮的替代方案。Polars 使用 Rust 開發,這是一種以效能著稱的語言,提供了快速且記憶體高效的 DataFrame 操作。Polars 使用的記憶體模型根據 Apache Arrow,這是一個跨語言的開發平台,用於在記憶體中表示資料,指定了一種標準化和語言無關的欄位記憶體格式,用於平面和層次資料。Arrow 允許零複製讀取和快速資料存取和交換,無需在語言和系統之間進行序列化。

事實上,不僅 Polars 使用 Arrow 作為記憶體中的格式,pandas DataFrame 和其他 Python 函式庫,如 NumPy 和 PySpark,也都使用 Arrow。這使得不同系統和工具之間的資料交換變得更加高效。

將 DuckDB 表格轉換為 Polars DataFrame

假設我們已經安裝了 pandas 和 DuckDB,我們現在可以將 population 表格轉換為 Polars DataFrame。首先,我們需要在 Python 環境中安裝 Polars 和 pyarrow:

pip install polars pyarrow

然後,我們可以使用 pl 函式將 population 表格轉換為 Polars DataFrame,並選取前五行的某些欄位:

import polars as pl

population_table = con.table("population")
result = (population_table
          .limit(5)
          .pl()
          [["Country", "Region", "Population"]]
          )
print(result)

輸出結果如下:

shape: (5, 3)
┌─────────────────┬───────────────────────────────────┬────────────┐
│ Country         │ Region                            │ Population │
│ ---             │ ---                               │ ---        │
│ str             │ str                               │ i64        │
╞═════════════════╪═══════════════════════════════════╪════════════╡
│ Afghanistan     │ ASIA (EX. NEAR EAST)              │ 31056997   │
│ Albania         │ EASTERN EUROPE ...                │ 3581655    │
│ Algeria         │ NORTHERN AFRICA ...               │ 32930091   │
│ American Samoa  │ OCEANIA ...                       │ 57794      │
│ Andorra         │ WESTERN EUROPE ...                │ 71201      │
└─────────────────┴───────────────────────────────────┴────────────┘

內容解密:

  1. con.table("population"):從 DuckDB 連線中取得名為 “population” 的表格。
  2. .limit(5):限制結果為前五行。
  3. .pl():將 DuckDB 表格轉換為 Polars DataFrame。
  4. [["Country", "Region", "Population"]]:選取 “Country”、“Region” 和 “Population” 三個欄位。

將 DuckDB 表格轉換為 Apache Arrow 表格

我們也可以將 DuckDB 表格轉換為 Apache Arrow 表格,以利用支援 Arrow 的各種工具和平台。使用 to_arrow_table 函式即可完成轉換:

arrow_table = population_table.to_arrow_table()

接下來,我們可以使用 Arrow 的 Python API 對資料進行進一步的操作。例如,假設我們對 NEAR EAST 地區的國家感興趣,想要檢索該地區前五個國家的國家名稱、地區和人口數量:

import pyarrow.compute as pc

result = (arrow_table
          .filter(pc.field("Region") == "NEAR EAST")
          .select(["Country", "Region", "Population"])
          .limit(5)
          )

內容解密:

  1. pc.field("Region") == "NEAR EAST":建立一個篩選條件,選取 “Region” 欄位等於 “NEAR EAST” 的列。
  2. .select(["Country", "Region", "Population"]):選取 “Country”、“Region” 和 “Population” 三個欄位。
  3. .limit(5):限制結果為前五列。

這段程式碼展示瞭如何使用 DuckDB、Polars 和 Apache Arrow 進行高效的資料操作和交換,充分利用了各個工具的優勢。

MotherDuck:雲端DuckDB的無伺服器分析平台

7.1 MotherDuck簡介

MotherDuck是一個協作式無伺服器分析平台,允許使用者在雲端資料函式庫和雲端儲存中查詢和分析資料。該平台支援透過瀏覽器或任何DuckDB API進行操作。無伺服器架構意味著使用者無需自行組態伺服器、叢集或資料函式庫例項,只需建立資料函式庫,其餘部分由服務自動處理。

MotherDuck於2023年6月推出封閉測試版,並於2023年9月正式開放使用。該平台與DuckDB Labs團隊緊密合作,以確保最佳的互操作性和雲端平台功能的可用性。使用者可在MotherDuck官方網站找到詳細的技術檔案。

7.1.1 工作原理

MotherDuck提供多種使用方式。當使用者註冊並登入服務後,可使用根據瀏覽器的MotherDuck網頁介面。此介面內建了一個特殊的DuckDB版本,能夠與MotherDuck服務進行通訊。該介面不僅可用於管理資料函式庫,還提供了一個根據筆記本的環境,用於輸入、執行查詢並檢視結果。

除了網頁介面,使用者還可透過CLI(命令列介面)或Python等語言與MotherDuck進行整合。MotherDuck作為DuckDB的一個擴充功能,使用者可透過md:motherduck:協定開啟資料函式庫時自動載入該擴充。此擴充功能增強了查詢解析器和引擎,使其能夠根據表格是否在本地或遠端進行適當的執行引擎選擇,並相應地整合資料。如有需要,部分本地資料會被傳送到伺服器進行聯合查詢或篩選,或者從遠端取得資料並在本地進行聯合查詢。

MotherDuck架構

MotherDuck的核心架構如圖7.1所示,主要由以下元件組成:

  • 服務層:負責身份驗證、管理、監控和計費等功能。
  • Ducklings:無伺服器的DuckDB計算例項,用於執行查詢的遠端部分。
  • 目錄:管理資料函式庫和表格的中繼資料。
  • 儲存層:負責內部儲存和維護。

服務層提供了安全身份驗證、授權、管理、監控和計費等功能。Duckling例項負責執行查詢的遠端部分,而目錄則暴露了資料函式庫和表格的中繼資料。

使用案例與最佳化建議

本章將進一步介紹如何建立、管理及分享MotherDuck資料函式庫,以及如何最佳化使用體驗。具體內容包括:

  • 使用網頁介面管理資料函式庫和執行查詢。
  • 透過CLI和程式語言API與MotherDuck互動。
  • 資料函式庫和查詢的最佳化技巧。

#### 內容解密:

此段落主要講解了MotherDuck的核心概念與其運作原理,包括其無伺服器架構、與DuckDB的整合方式以及核心元件的功能。接下來的章節將進一步探討如何實際操作與最佳化MotherDuck的使用體驗。

import duckdb
# 連線至MotherDuck
con = duckdb.connect(database='md:我的資料函式庫', read_only=False)
# 執行查詢
result = con.execute("SELECT * FROM my_table").fetchdf()
print(result)

#### 內容解密:

這段程式碼展示瞭如何使用Python連線至MotherDuck並執行查詢。首先,我們匯入了duckdb模組,並使用duckdb.connect方法連線到指定的MotherDuck資料函式庫。read_only=False引數表示我們具有寫入許可權。接著,我們執行了一個簡單的SQL查詢,將結果提取到pandas DataFrame中並列印出來。此範例說明瞭如何透過程式設計方式與MotherDuck互動。

7.1 MotherDuck 簡介與優勢

7.1.1 MotherDuck 架構與特點

MotherDuck 是一個根據 DuckDB 的雲端資料倉儲服務,提供高效、簡潔的資料分析體驗。其核心架構採用了儲存與計算分離的設計,這種設計未來對於使用 MotherDuck 的成本會有顯著影響。

架構圖

@startuml
skinparam backgroundColor #FEFEFE
skinparam defaultTextAlignment center
skinparam rectangleBackgroundColor #F5F5F5
skinparam rectangleBorderColor #333333
skinparam arrowColor #333333

title 架構圖

rectangle "查詢執行" as node1
rectangle "管理與驗證" as node2
rectangle "查詢處理" as node3
rectangle "後設資料管理" as node4
rectangle "內部儲存" as node5
rectangle "外部資料來源" as node6

node1 --> node2
node2 --> node3
node3 --> node4
node4 --> node5
node5 --> node6

@enduml

7.1.2 為何選擇 MotherDuck?

MotherDuck 提供了一個簡化且高效的資料倉儲解決方案。對於大多數使用者而言,其資料量並未達到需要分散式系統支援的 TB 級別。MotherDuck 利用雲端儲存和 DuckDB 作為查詢引擎,能夠有效處理中小型資料分析任務。

典型應用場景

  • 監控系統資料分析:例如監測數百或數千個能源生產站點的季度小時資料,這類別資料量通常只有幾 GB,完全在 MotherDuck 的處理能力範圍內。
  • 異構資料來源查詢:可用於查詢儲存在不同格式(如 Parquet、CSV、Apache Iceberg)的冷資料,並可與 MotherDuck 中的熱資料進行聯合查詢。
  • 伺服器端資料應用:可作為資料應用、儀錶板和 API 的無伺服器後端,專門用於執行分析查詢。

7.2 入門

7.2.1 使用 MotherDuck UI

MotherDuck 提供了一個根據 Web 的 UI 介面(https://app.motherduck.com),用於管理和查詢遠端資料函式庫、管理帳戶設定以及儲存存取遠端資料來源所需的金鑰。

主要功能

  • 查詢執行與結果展示:支援 SQL 查詢,並提供內嵌的條形圖展示結果。
  • 資料函式倉管理:列出資料函式庫、表及其列,並支援上傳 CSV 和 Parquet 檔案。
  • 互動式結果處理:查詢結果會在本地 DuckDB 例項中快取,支援即時排序、透視和篩選。

7.2.2 使用 DuckDB 連線 MotherDuck

要透過 DuckDB 連線 MotherDuck,需要使用令牌(Token)進行身份驗證。使用者需先註冊並登入 MotherDuck 帳戶,然後取得 API Token 以便在 CLI 或語言繫結中使用。

連線步驟

  1. 登入 MotherDuck 帳戶。
  2. 取得 API Token。
  3. 在 DuckDB CLI 或語言繫結中進行身份驗證。
-- 示例 SQL 陳述式,用於連線到 MotherDuck
ATTACH 'md:' USING motherduck_token='your_api_token';

連線說明

此連線方式允許使用者在本地 DuckDB 環境中存取和管理 MotherDuck 中的資料函式庫,實作靈活的資料分析和處理。

使用 MotherDuck 的基礎與進階功能

連線 MotherDuck 與初始設定

當你連線到 MotherDuck 而未指定特定資料函式庫時,系統預設會連線到名為 my_db 的預設資料函式庫。你可以直接查詢該資料函式庫中的表格,或使用 USE 命令切換到其他資料函式庫。

首先,在 CLI 中執行 .open md: 指令以開啟預設資料函式庫。若尚未驗證,系統會提示進行單一登入(SSO)授權,並顯示以下訊息:

  1. 開啟連結以登入帳戶:https://auth.motherduck.com/activate
  2. 輸入指定的驗證碼:XXXX-XXXX

完成驗證後,終端機會顯示:

Token successfully retrieved [√]

你可以將取得的 token 儲存為環境變數,以避免每次登入:

$ export motherduck_token='eyJhbGciOiJI..._Jfo'

或者在連線時直接使用 token:

.open 'md:?motherduck_token=eyJhbGciOiJI..._Jfo'

在 Python 環境中,同樣可以透過 token 連線:

import duckdb
con = duckdb.connect('md:?motherduck_token=eyJhbGciOiJI..._Jfo')

充分利用 MotherDuck 的功能

MotherDuck 擴充套件了 DuckDB 的功能,使其能夠與雲端服務無縫整合。主要功能包括:

  • 將本地資料函式庫上傳至雲端
  • 管理資料函式庫(建立、刪除、列出)
  • 透過 URL 分享資料函式庫,並可將其附加到本地 DuckDB 例項
  • 存取 S3 儲存桶中的資料
  • 控制查詢的執行位置(完全遠端、完全本地或混合模式)

此外,MotherDuck 提供了 AI 相關功能,例如自動描述資料函式庫結構並生成或修正 SQL 查詢。

上傳本地資料函式庫至 MotherDuck

假設你已經有一個名為 countries.duckdb 的本地資料函式庫,可以透過以下步驟上傳至 MotherDuck:

  1. 開啟本地資料函式庫:
    .open countries.duckdb
    
  2. 若資料函式庫不存在,可先建立一個範例表格:
    CREATE TABLE cities AS 
    SELECT * 
    FROM (VALUES ('Amsterdam', 1), ('London', 2)) cities(Name, Id);
    
  3. 切換至 MotherDuck 預設資料函式庫並載入擴充套件:
    .open md:
    
  4. 建立遠端資料函式庫並上傳本地資料:
    CREATE DATABASE "countries" FROM 'countries.duckdb';
    

上傳時間取決於資料函式庫大小和網路速度。在我們的測試中,上傳一個 16 GB 的資料函式庫大約需要 40 分鐘。未來,MotherDuck 計畫最佳化上傳效能。

驗證上傳結果

上傳完成後,你可以查詢新建立的資料函式庫:

USE countries;
FROM cities;

輸出結果應顯示你剛建立的表格內容:

┌───────────┬───────┐
│ Name      │ Id    │
│ varchar   │ int32 │
├───────────┼───────┤
│ Amsterdam │ 1     │
│ London    │ 2     │
└───────────┴───────┘

使用不同查詢模式

你可以控制查詢是在本地還是遠端執行,甚至混合兩者。例如,直接查詢遠端資料函式庫中的表格:

FROM countries.cities;

或者切換到特定資料函式庫後再查詢:

USE countries;
FROM cities;

重點解析與最佳實踐

  1. 上傳與分享資料函式庫:將本地 DuckDB 資料函式庫上傳至 MotherDuck,可實作與團隊成員的協同工作。
  2. 查詢模式選擇:可根據需求選擇查詢的執行位置(本地或遠端),提升靈活性與效能。
  3. AI 輔助功能:利用 MotherDuck 的 AI 功能自動生成或最佳化 SQL 查詢,提升開發效率。

程式碼範例與解析

以下是一個完整的 Python 範例,用於連線 MotherDuck 並執行查詢:

import duckdb

# 建立連線並指定 MotherDuck token
con = duckdb.connect('md:?motherduck_token=eyJhbGciOiJI..._Jfo')

# 執行查詢
result = con.execute("SELECT * FROM countries.cities").fetchdf()

# 輸出結果
print(result)

# 關閉連線
con.close()

內容解密:

  1. 匯入 duckdb 模組:使用 import duckdb 將 DuckDB 的 Python 繫結匯入程式中。
  2. 建立連線duckdb.connect() 方法用於建立與 MotherDuck 的連線,並透過 motherduck_token 進行身份驗證。
  3. 執行 SQL 查詢:使用 con.execute() 方法執行 SQL 查詢,並透過 fetchdf() 將結果轉換為 Pandas DataFrame。
  4. 輸出結果:將查詢結果列印出來。
  5. 關閉連線:使用 con.close() 方法關閉與 MotherDuck 的連線,釋放資源。

此範例展示瞭如何使用 Python 與 MotherDuck 進行互動,並執行遠端 SQL 查詢。透過這種方式,你可以將本地的 DuckDB 資料函式庫遷移至雲端,並實作高效的協同工作與大規模資料處理。