DatabricksでSQLウェアハウスを構築して、SQLAlchemy+AlembicでDB Migrationを行う

# はじめに

DatabricksのSQLウェアハウスは、Databricks Appsのデータベースとして使用できるものです。そのため、アプリケーションと統合されたデータベースマイグレーションを行い、データベースのバージョン管理を行えることを目指します。

本記事では、以下の内容について解説します：
- DatabricksでSQLウェアハウスを構築する方法
- SQLAlchemyとAlembicを使用してデータベースマイグレーションを行う方法

## 前段
- [Azure DatabricksでDatabricks Appsを検証するための環境構築](https://qiita.com/kei1-dev/items/c5d1f21687bd23489166)
- [Databricks Apps でカスタムアプリのデプロイ](https://qiita.com/kei1-dev/items/3e749e2519535f8c0d56)
- [FastAPIにSPAアプリケーションを統合する](https://qiita.com/kei1-dev/items/09fb914e724016b654eb)
- [Databricks AppsにSPAアプリを含めたカスタムアプリを作成する](https://qiita.com/kei1-dev/items/3e11a598436f52e0ff06)
- [Databricks WorkspaceとGitHubを連携してDatabricks Appsにデプロイする](https://qiita.com/kei1-dev/items/beb8d7f379828253827b)
- [Databricks WebTerminalを有効化する](https://qiita.com/kei1-dev/items/344072967fcafa54a4a9)

# 手順
## DatabricksでSQL Workspaceを構築する
1. 画面左メニューからSQL>SQLウェアハウスを選択、画面上部の「SQLウェアハウスを作成」ボタンを押下
   ![1_SQLWarehouse_Top.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479886/7e15664c-ddcc-33df-94ff-ffa855d7fd67.png)


2. SQLウェアハウスの名前を入力し、他はデフォルト設定のまま、「作成」ボタンを押下
   ![2_SQLWarehouse_Create.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479886/b43f2b4c-9013-3e75-174e-4610af58361f.png)


3. 権限管理設定はデフォルト設定のまま、×ボタンを押下
   ![3_SQLWarehouse_Permission.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479886/9a817dd2-7982-6e0d-ac5a-856d6328c1df.png)


4. SQLウェアハウスの一覧画面から作成したSQLウェアハウスを選択し、概要を確認する
   ![4_SQLWarehouse_Overview.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479886/b037a52f-3314-59f3-cb8b-dfa49467290f.png)


## SQLAlchemy+AlembicでDB Migrationを行う(アプリ側設定は概要のみ記載)
※ コードベースは[過去の記事](https://qiita.com/kei1-dev/items/3e11a598436f52e0ff06)のものを使用しています
※ 作業環境は[過去の記事で紹介したWeb Terminal](https://qiita.com/kei1-dev/items/344072967fcafa54a4a9)を使用しています
1. SQLAlchemyとAlembicをインストールする
   ```bash
   pip install sqlalchemy alembic databricks-sql-connector
   ```

2. models.pyを作成し、テーブルのモデルを作成する
    ```python
    from sqlalchemy import Column, Integer, String, DateTime
    from sqlalchemy.ext.declarative import declarative_base
    from datetime import datetime

    Base = declarative_base()

    class Item(Base):
    __tablename__ = "items"

    id = Column(Integer, primary_key=True, index=True)
    item_id = Column(String, index=True)
    query = Column(String)
    created_at = Column(DateTime, default=datetime.utcnow)
    updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
    ```

3. alembicの設定ファイルを作成する
    ```bash
    alembic init alembic
    ```

4. alembic.iniを編集する
   ```bash
   # 以下の環境変数が必要です：
   # DATABRICKS_SERVER_HOSTNAME - Databricksのホスト名
   # DATABRICKS_HTTP_PATH - SQLウェアハウスのHTTPパス
   # DATABRICKS_TOKEN - アクセストークン
   sqlalchemy.url = databricks://token:%(DATABRICKS_TOKEN_PROD)s@%(DATABRICKS_SERVER_HOSTNAME_PROD)s?http_path=%(DATABRICKS_HTTP_PATH_PROD)s&catalog=%(DATABRICKS_CATALOG_PROD)s&schema=%(DATABRICKS_SCHEMA_PROD)s
   ```

5. env.pyを編集する
   engine_from_configだとエラーになったので、create_engineに書き換えました。
   ```python
   connectable = create_engine(DATABASE_URL, connect_args={"verify": False})
   ```

6. SQLウェアハウスの一覧画面から作成したSQLウェアハウスを選択し、接続の詳細からサーバのホスト名、HTTPパスを取得する
   ![5_SQLWarehouse_ConnectionDetails.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479886/ca6f465c-249c-7328-074b-b7b033177ebe.png)


7. 同画面からPythonを選択し、画面内「新規トークンを作成」ボタンを押下し、トークンを作成、コピーする
   ![6_SQLWarehouse_CreateToken.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479886/8447f5bf-c398-df95-7aaa-deb66b9894cf.png)

8. 取得した内容を環境変数に設定する
   ```bash
   export ENV=production
   export DATABRICKS_SERVER_HOSTNAME_PROD=<サーバのホスト名>
   export DATABRICKS_HTTP_PATH_PROD=<HTTPパス>
   export DATABRICKS_TOKEN_PROD=<トークン>
   export DATABRICKS_CATALOG_PROD=<カタログ名>(初期値はワークスペース名)
   export DATABRICKS_SCHEMA_PROD=<スキーマ名>(初期値はdefault)
   ```
9.  コマンドを実行して、マイグレーションを実行する
    ```bash
    alembic revision --autogenerate -m "Initial migration"
    alembic upgrade head
    ```
    実行すると、なぜかエラーになりますが、マイグレーションは正常に実行されています。
    ```
    sqlalchemy.exc.DatabaseError: (databricks.sql.exc.ServerOperationError) [UC_COMMAND_NOT_SUPPORTED.WITHOUT_RECOMMENDATION] The command(s): CreateIndex are not supported in Unity Catalog.
    ```
10. マイグレーションの確認
    画面左メニューのカタログから、指定したカタログ、スキーマを選択すると、以下2テーブルが作成されていることが確認できます
    - alembic_version
    - items
  
    ![09_SQLWarehouse_MigrationCheck.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479886/d496a10d-3310-e34e-ebee-d23ee5e8e401.png)



# まとめ

本記事では、以下の内容について解説しました：

1. DatabricksでのSQLウェアハウスの構築
   - SQLウェアハウスの作成と基本設定

2. SQLAlchemy + Alembicを使用したDBマイグレーション
   - 必要なパッケージのインストール（sqlalchemy, alembic, databricks-sql-connector）
   - モデル定義とマイグレーション設定
   - 環境変数を使用した接続設定
   - マイグレーションの実行手順

3. 注意点
   - Unity Catalogの制限により、CreateIndexコマンドはサポートされていないが、マイグレーション自体は正常に実行される
   - 接続設定には環境変数（ホスト名、HTTPパス、トークン、カタログ名、スキーマ名）が必要

# 参考

- [Databricks SQLAlchemy](https://docs.databricks.com/ja/dev-tools/sqlalchemy.html#sqlalchemy-v2)