🦆

Databricks上からDuckDBを触ってみた

2024/09/23に公開

触ってみるったら触ってみるんだ

このまえDAISでデモもしてたし動くはず。

セットアップ

まずはモジュールインストール。

%pip install duckdb pandas deltalake
dbutils.library.restartPython()

なんか、version 1.1.0のレポジトリにはuc_catalogのモジュールが取り込まれてないっぽいので1.0.0で試す。
取り込まれたっぽいので1.1.0で試し直す。

そして読み込み

import duckdb
import pyarrow.dataset as ds
from deltalake import DeltaTable

まずS3上のParquetファイルを読んでみる

S3用のモジュールの読み込み

duckdb.sql("""
INSTALL httpfs;
LOAD httpfs;
""")

AWSアクセス用のSECRETの設定

duckdb.sql("""
CREATE SECRET delta_s3 (
    TYPE S3,
    KEY_ID '<aws-secret-access-id>',
    SECRET '<aws-secret-access-key>',
    SESSION_TOKEN '<aws-session-token>',
    REGION 'us-west-2',
    SCOPE 's3://<S3-bucket>'
)
""")

では実行

duckdb.sql("""
SELECT * FROM read_parquet('s3://<S3-bucket>/<path>/file.parquet') WHERE id=23261;
""")
┌───────┬────────────────────────────┬──────────────┬─────────┐
│  id   │         timestamp          │    string    │  float  │
│ int32 │         timestamp          │   varchar    │  float  │
├───────┼────────────────────────────┼──────────────┼─────────┤
│ 23261 │ 2024-03-29 14:26:07.375612 │ string_23261 │ 23261.0 │
└───────┴────────────────────────────┴──────────────┴─────────┘

はい!成功!速いね!

duckdb.sql("""
DESCRIBE TABLE 's3://<S3-bucket>/<path>/file.parquet'
""")
┌─────────────┬─────────────┬─────────┬─────────┬─────────┬─────────┐
│ column_name │ column_type │  null   │   key   │ default │  extra  │
│   varchar   │   varchar   │ varchar │ varchar │ varchar │ varchar │
├─────────────┼─────────────┼─────────┼─────────┼─────────┼─────────┤
│ id          │ INTEGER     │ YES     │ NULL    │ NULL    │ NULL    │
│ timestamp   │ TIMESTAMP   │ YES     │ NULL    │ NULL    │ NULL    │
│ string      │ VARCHAR     │ YES     │ NULL    │ NULL    │ NULL    │
│ float       │ FLOAT       │ YES     │ NULL    │ NULL    │ NULL    │
└─────────────┴─────────────┴─────────┴─────────┴─────────┴─────────┘

Delta Tableを読んでみる

まずDelta Table書き出してみて

# JSONファイルのパス
json_s3_path = "s3://<s3-bucket>/load/nytaxi.json"

# JSONファイルを読み込みデータフレームに変換
df_trips = spark.read.format("json").load(json_s3_path)

# Delta Table形式で書き出し
path = "/Volumes/test_catalog/test_schema/duckdb_volumes/delta_table"
df_trips.write.format("delta").mode("overwrite").save(path)

これで。

duckdb.sql("""
SELECT *
FROM delta_scan('/Volumes/test_catalog/test_schema/duckdb_volumes/delta_table');
""")
┌─────────────┬─────────────┬────────────┬──────────────────────────┬──────────────────────────┬───────────────┐
│ dropoff_zip │ fare_amount │ pickup_zip │  tpep_dropoff_datetime   │   tpep_pickup_datetime   │ trip_distance │
│    int64    │   double    │   int64    │         varchar          │         varchar          │    double     │
├─────────────┼─────────────┼────────────┼──────────────────────────┼──────────────────────────┼───────────────┤
│       11238 │        18.5 │      10003 │ 2016-02-16T22:59:25.000Z │ 2016-02-16T22:40:45.000Z │          5.35 │
│       10001 │        21.5 │      10282 │ 2016-02-05T16:26:03.000Z │ 2016-02-05T16:06:44.000Z │           6.5 │
│       10003 │         5.5 │      10119 │ 2016-02-08T07:44:14.000Z │ 2016-02-08T07:39:25.000Z │           0.9 │
│       11222 │        13.5 │      10001 │ 2016-02-29T22:38:09.000Z │ 2016-02-29T22:25:33.000Z │           3.5 │
│       10028 │         3.5 │      10028 │ 2016-02-03T17:23:24.000Z │ 2016-02-03T17:21:02.000Z │           0.3 │
│       10005 │         5.0 │      10038 │ 2016-02-10T00:53:04.000Z │ 2016-02-10T00:47:44.000Z │           0.0 │
│       11377 │        21.5 │      10001 │ 2016-02-19T03:44:56.000Z │ 2016-02-19T03:24:25.000Z │          6.57 │
(以下略)

よめるやーーーーーん!
そしてVolumes経由だとSECRET要らないで行けるのでちょっと楽ちんぽさの広がりを見せるね

Unity Catalog経由でDelta Tableを読んでみる

次はUnity Catalog経由でDelta Table読んでみたいよ
再チャレンジだよ〜!

最初実行したら
curl: (77) Problem with the SSL CA cert (path? access rights?)
のメッセージがでていたので、こちらCA証明書をいれてみる

!sudo mkdir -p /etc/pki/tls/certs/
!sudo cp /Workspace/Users/hogehoge/cacert.pem /etc/pki/tls/certs/ca-bundle.crt
duckdb.sql("""
INSTALL uc_catalog from core_nightly;
INSTALL delta from core;
LOAD delta;
LOAD uc_catalog;
CREATE SECRET (
	TYPE UC,
  TOKEN '<Databricks PAT Token>',
  ENDPOINT 'https://<Workspace URL>',
  AWS_REGION 'us-west-2'
);
ATTACH 'kuwano_catalog' AS kuwano_catalog (TYPE UC_CATALOG);
""")
duckdb.sql("""
SHOW ALL TABLES;
""")
┌────────────────┬───────────────────────┬─────────────────────┬──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┬────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┬───────────┐
│    database    │        schema         │        name         │                                                                                                                                                                                                                   column_names                                                                                                                                                                                                                   │                                                                                                    column_types                                                                                  
見づらいので以下略w
duckdb.sql("""
SELECT * FROM kuwano_catalog.kuwano_demo_sample.kuwano_demo_table;
""")
WARNING:root:Unexpected exception finding object shape
┌───────┐
│  id   │
│ int64 │
├───────┤
│     0 │
│     1 │
│     2 │
│     3 │
│     4 │
│     5 │
└───────┘

なんか出てるのは気になるけどとりあえずUnity Catalog経由でも読めたよ!やったね!

Discussion