S3に格納されているCSVファイルのDatabricksへの取り込み

簡単そうに見えなくもないですが、いくつか選択肢があるのでそれぞれの良し悪し含めてウォークスルーしていきます。

マニュアルはこちらですが、それほど親切ではありません(すみません、あとで修正します)。

https://docs.databricks.com/ja/ingestion/onboard-data.html

以下の2つの観点で選択肢を検討する必要があります。

- DatabricksからS3へのアクセス方法
- S3からDatabricksへの取り込み

# S3の準備

AWSのコンソールからS3バケットを作成します。ここでは`taka-uc-external-location-bucket`という名前にしています。
![Screenshot 2024-05-14 at 20.17.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/1088bff0-27ad-dd95-fa97-76f4eadb147e.png)

適当なCSVファイルをアップロードしておきます。
![Screenshot 2024-05-14 at 20.32.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/6a7c6792-2b0f-21bf-e449-05efc17927d2.png)

# DatabricksからS3へのアクセス

Databricksから既存のS3バケットにアクセスするには以下の設定が必要です。

- [ストレージ認証情報](https://docs.databricks.com/ja/connect/unity-catalog/storage-credentials.html): DatabricksからS3へのアクセスを許可するIAMロールをラッピングするオブジェクトです。
- [外部ロケーション](https://docs.databricks.com/ja/connect/unity-catalog/external-locations.html): アクセスを許可するS3のパスと上記のストレージ認証情報をラッピングするオブジェクトです。

そして、アクセスの方法としては上記の外部ロケーション経由でアクセスするか、[ボリューム](https://docs.databricks.com/ja/connect/unity-catalog/volumes.html)として設定してアクセスするかの選択肢があります。

## 外部ロケーションの作成

まずは、外部ロケーションから作成します。

### Databricksカタログエクスプローラでの作業

カタログエクスプローラの**外部データ > 外部ロケーション**にアクセスし、右上の**ロケーションを作成**をクリックします。
![Screenshot 2024-05-14 at 20.35.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/69264fd9-793e-fa9a-f35a-26f99eab58ec.png)

**AWSクイックスタート**を選択して、**次のページ**をクリックします。
![Screenshot 2024-05-14 at 20.35.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/f472dfb4-c010-f2a2-be6d-a003ea50c8d9.png)

:::note info
**注意**
**AWSクイックスタート**の方法の場合には、ストレージ認証情報の作成をスキップできます。手動の場合は、ご自身でストレージ認証情報を作成する必要があります。
:::

バケット名に`s3://taka-uc-external-location-bucket`を指定して、下にある**新規トークンを生成**をクリックします。
![Screenshot 2024-05-14 at 20.38.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/34858a8e-4f75-70fb-8eef-6440ea970e57.png)

表示されるパーソナルアクセストークンをコピーしておきます。この後のCloudFormationテンプレートで指定します。

:::note warn
**警告**
- パーソナルアクセストークンは厳重に管理してください。
- このパーソナルアクセストークンは60分で無効になるので、それまでに次のステップを完了してください。
:::

**クイックスタートで開始**をクリックします。

### AWSコンソールでの作業

AWSコンソールにログインしていない場合にはログインします。
![Screenshot 2024-05-14 at 20.42.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/1d33c47d-f032-1196-cba5-5f6d870c0676.png)

CloudFormationのテンプレートが表示されます。
![Screenshot 2024-05-14 at 20.43.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/0fb5a599-1e21-bb4b-1313-874663fc716c.png)

**Databricks Personal Access Token**に上のステップでコピーしたパーソナルアクセストークンを貼り付けます。
![Screenshot 2024-05-14 at 20.44.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/c9b9b427-e19e-c277-1ab8-a8c5c5def448.png)
![Screenshot 2024-05-14 at 20.46.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/9ab976a4-8a74-da2d-f271-c72683e563d0.png)

**機能**の部分のチェックをつけて、**スタックの作成**をクリックするとスタックの構築がスタートします。
![Screenshot 2024-05-14 at 20.47.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/7c3f1ff8-f418-e7ff-0a5d-5e724bf997b2.png)

`CREATE_COMPLETE`になるまで待ちます。
![Screenshot 2024-05-14 at 20.50.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/d9fd310a-0dbb-cb6e-c25a-4e47cf22a3fe.png)

### Databricksカタログエクスプローラでの動作確認

`CREATE_COMPLETE`になったら、Databricksのカタログエクスプローラに戻って**OK**をクリックします。
![Screenshot 2024-05-14 at 20.50.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/e3cef682-89ea-480a-306c-aa17e4a8c389.png)

これで外部ロケーションが作成されました。
![Screenshot 2024-05-14 at 20.51.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/023a45b9-2e7d-d46c-1625-f9180e74e534.png)

**接続のテスト**をクリックします。
![Screenshot 2024-05-14 at 20.53.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/f5f94f24-9b4c-d98e-84e0-a47acb5bc467.png)

テストが通過したらOKです。
![Screenshot 2024-05-14 at 20.54.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/09483b23-f43d-c3a2-30c6-682e9125339a.png)

**閲覧**タブでもCSVファイルを確認できるはずです。
![Screenshot 2024-05-14 at 20.55.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/98f01335-8b89-8112-1003-6963c6e5d463.png)

この時点でもノートブックからCSVにアクセスすることは可能です。

```py
df = spark.read.csv("s3://taka-uc-external-location-bucket/data/japan_cases_20220818.csv", header=True)
display(df)
```
![Screenshot 2024-05-14 at 21.04.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/84ce69ee-1027-fcff-fa8b-e07b69a9d72e.png)

ただ、外部ロケーションの場合、`s3://`のプレフィクスを用いてアクセスするので、pandasやシェルからはアクセスできません。そこでボリュームの出番です。外部ロケーションを**外部ボリューム**として設定することで、以下のようなメリットを享受できます。

- 言語やAPIを問わずに統一されたパスでファイルにアクセスできるようになります。
- カタログエクスプローラのUIから簡単にファイルを追加することができます。
- ファイルの格納場所をUnity Catalogの[カタログ、スキーマ](https://docs.databricks.com/ja/data-governance/unity-catalog/create-catalogs.html)の枠組みで整理できます。

## ボリュームの作成

カタログエクスプローラで適当なカタログ、スキーマを選択します。右上の**作成 > ボリュームを作成**をクリックします。
![Screenshot 2024-05-14 at 21.06.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/e46cc797-644b-30b4-8a8e-51f2051f268d.png)

ボリュームの名称を入力し、外部ボリュームを選択します。
![Screenshot 2024-05-14 at 21.08.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/83fd427f-1851-059c-472b-68584cb29362.png)

上のステップで作成した外部ロケーションを選択します。
![Screenshot 2024-05-14 at 21.10.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/f22f3971-f9ac-8ab8-678f-38c5749aa7fd.png)

**作成**をクリックします。これで外部ボリュームが作成されました。なお、ボリュームには`/Volumes/<カタログ名>/<スキーマ(データベース)名>/<ボリューム名>/`というパスでアクセスできます。
![Screenshot 2024-05-14 at 21.11.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/ea4cb52f-3a38-c303-0bb5-f9fc49bc5b6b.png)

CSVファイルも確認できます。
![Screenshot 2024-05-14 at 21.11.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/310b1c39-ebab-87ca-ccbf-343687cc9de9.png)

カタログエクスプローラからファイルの追加も可能です。
![Screenshot 2024-05-14 at 21.13.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/c966fbf7-3eb5-a6a7-eb81-9fe2dfc2672f.png)

追加されたファイルはAWSのコンソールでも確認できます。
![Screenshot 2024-05-14 at 21.13.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/e788500a-2119-f8ee-9e20-52b78781f286.png)

# S3からDatabricksへの取り込み

ここまでのステップで、DatabricksからCSVを格納しているS3にボリューム経由でアクセスできるようになりました。

```py
df = spark.read.csv("/Volumes/main/ingested_s3/csv_volume/data/japan_cases_20220818.csv", header=True)
display(df)
```
![Screenshot 2024-05-14 at 21.15.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/29d29fe5-bf1c-a615-32ca-84cc02212809.png)

しかし、この状態では常にパスを意識する必要がありますし、SQLを使うのも困難です。おすすめはカタログにテーブルとして登録するというものになります。これによって、リネージ、行列レベルのアクセス権、モニタリングなどのUnity Catalogの[様々な機能](https://docs.databricks.com/ja/data-governance/unity-catalog/index.html)を活用できるようになります。

```py
df = spark.read.csv("/Volumes/main/ingested_s3/csv_volume/data/japan_cases_20220818.csv", header=True)
df.write.saveAsTable("main.ingested_s3.covid_data")
```

これでカタログにテーブルが登録されましたので、SQLでも容易にアクセスできるようになります。
![Screenshot 2024-05-14 at 21.29.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/d8761424-83c4-b639-cf16-0e881c5f4ed9.png)

```py
df = spark.sql("SELECT * FROM main.ingested_s3.covid_data")
display(df)
```
```sql
%sql
SELECT * FROM main.ingested_s3.covid_data
```
![Screenshot 2024-05-14 at 21.32.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/c32a3859-74f8-c53b-eb63-b4b778eaaaf1.png)

# まとめ

| 観点 | おすすめ |
|:--|:--|
| DatabricksからS3へのアクセス方法  | [ボリューム](https://docs.databricks.com/ja/connect/unity-catalog/volumes.html)経由でのアクセス  |
|  S3からDatabricksへの取り込み | カタログ配下の[テーブル](https://docs.databricks.com/ja/data-governance/unity-catalog/create-tables.html)として取り込み  |

ご活用ください！

### はじめてのDatabricks

[はじめてのDatabricks](https://qiita.com/taka_yayoi/items/8dc72d083edb879a5e5d)

### Databricks無料トライアル

[Databricks無料トライアル](https://databricks.com/jp/try-databricks)