Simple Data Integrator (SDI) 応用編：データ連携 (PostgreSQLからSnowflakeへの連携例)

:::note info
Simple Data Integrator (SDI) バージョン2.0.2024.5から、ODBC経由でSnowflakeへのデータ同期パフォーマンスが大幅に改善されました。以前のバージョンをご利用の方には、バージョンアップをおすすめします。
:::

# はじめに
SaaS型データプラットフォームであるSnowflakeをデータウェアハウスとして採用するケースが増えています。既存システムとSnowflakeとのデータ連携が必要になる場面も多くなっており、Simple Data Integratorを使用してその連携が可能です。ここでは、PostgreSqlを例にしてそのデータ連携手順について説明します。ほかのデータベースの手順は類似します。

# 前提条件
以下の環境が整っていることを確認してください：
1. PostgreSQLデータベース: ソースデータベースとしてのPostgreSQLへのアクセス権。
2. Snowflakeアカウント: ターゲットシステムとしてのSnowflake環境。
3. ODBCドライバー: Snowflakeへの接続に使用するODBCドライバーがインストールされていること。
4. Simple Data Integrator: Simple Data Integratorがインストールされていること。


# 構成図
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/560129/570b3cbf-90d1-b762-4098-cda7f9c45ce5.png)

※一般的なカラムタイプを使用したSnowflakeテーブルを作成し、動作確認を行います。

### Source  (PostgreSQL)
スキーマ名：public
テーブル名：sample_table
<table>
<tr>
<td>
テーブル構造
</td>
</tr>
<tr>
<td>

|PK|カラム名|型|
|-|-|-|
|![key_icon.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/560129/292a6047-9fbb-db98-6f7c-52db406207d9.png)|id|SERIAL|
||name|VARCHAR|
||description|VARCHAR|
||price|NUMERIC(10,2)|
||created_at|TIMESTAMP|
||last_updated_at|TIMESTAMPTZ|
||active|BOOLEAN|
||item_weight|FLOAT8|
||start_date|DATE|
||start_time|TIME|
||category|VARCHAR(50)|
||binary_data|BYTEA|
||unique_code|VARCHAR(10)|
||image_data|BYTEA|
</td>
</tr>
<tr>
<td>
DDL
</td>
</tr>
<tr>
<td>

```
CREATE TABLE public.sample_table (
    id SERIAL PRIMARY KEY,
    name VARCHAR,
    description VARCHAR,
    price NUMERIC(10,2),
    created_at TIMESTAMP,
    last_updated_at TIMESTAMPTZ,
    active BOOLEAN,
    item_weight FLOAT8,
    start_date DATE,
    start_time TIME,
    category VARCHAR(50),
    binary_data BYTEA,
    unique_code VARCHAR(10),
    image_data BYTEA
);

 ``` 
</td>
</tr>

<tr>
<td>
Test Data
</td>
</tr>
<tr>
<td>

```
INSERT INTO public.sample_table 
(name, description, price, created_at, last_updated_at, active, item_weight, start_date, start_time, category, binary_data, unique_code, image_data)
VALUES
('Item 1', 'Description of item 1', 100.50, NOW(), NOW(), TRUE, 1.25, '2024-01-01', '12:00:00', 'Category A', '\\xDEADBEEF', 'UNQ001',  '\\xAAFF'),
('Item 2', 'Description of item 2', 150.75, NOW(), NOW(), FALSE, 0.75, '2024-02-01', '15:30:00', 'Category B', '\\xCAFEBABE', 'UNQ002',  '\\xBBCC');
 ``` 
</td>
</tr>
</table>



### Target　(Snowflake)
スキーマ名：PUBLIC
テーブル名：SAMPLE_TABLE
<table>
<tr>
<td>
テーブル構造
</td>
</tr>
<tr>
<td>

|PK|カラム名|型|
|-|-|-|
|![key_icon.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/560129/292a6047-9fbb-db98-6f7c-52db406207d9.png)|ID|NUMBER(38,0)|
||NAME|VARCHAR(16777216)|
||DESCRIPTION|VARCHAR(16777216)|
||PRICE|NUMBER(10,2)|
||CREATED_AT|TIMESTAMP_NTZ(9)|
||LAST_UPDATED_AT|TIMESTAMP_TZ(9)|
||ACTIVE|BOOLEAN|
||ITEM_WEIGHT|FLOAT|
||START_DATE|DATE|
||START_TIME|TIME(9)|
||CATEGORY|VARCHAR(50)|
||BINARY_DATA|BINARY(8388608)|
||UNIQUE_CODE|VARCHAR(10)|
||IMAGE_DATA|BINARY(8388608)|

</td>
</tr>
<tr>
<td>
DDL
</td>
</tr>
<tr>
<td>

```
create or replace TABLE TESTDB.PUBLIC.SAMPLE_TABLE (
	ID NUMBER(38,0) NOT NULL autoincrement start 1 increment 1 noorder,
	NAME VARCHAR(16777216),
	DESCRIPTION VARCHAR(16777216),
	PRICE NUMBER(10,2),
	CREATED_AT TIMESTAMP_NTZ(9),
	LAST_UPDATED_AT TIMESTAMP_TZ(9),
	ACTIVE BOOLEAN,
	ITEM_WEIGHT FLOAT,
	START_DATE DATE,
	START_TIME TIME(9),
	CATEGORY VARCHAR(50),
	BINARY_DATA BINARY(8388608),
	UNIQUE_CODE VARCHAR(10),
	IMAGE_DATA BINARY(8388608),
	primary key (ID)
);
 
 ``` 

</td>
</tr>
</table>

### 処理フロー
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/560129/2935152d-7ce8-23dc-909a-5a339e19c363.png)



# 設定
### １．SnowflakeへのODBC設定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/560129/77d512a5-0744-0ee6-e992-a4b903ea3afd.png)
Data Source名：`Snowflake`
参考資料：
https://docs.snowflake.com/ja/developer-guide/odbc/odbc-windows

### ２．コネクション設定
Source DB、Target　DB への接続を設定。
|ソースコネクション名|ターゲットコネクション名|
|-|-|
|POSTGRE - Public<br />![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/560129/3e8154e9-e0df-8c1f-cb77-172d75e191bf.png)|SNOWFLAKE<br />![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/560129/d4683da8-18d5-9a18-492d-37618b026a90.png)|
|公式資料：<br />https://ja.sdi.ricct.com/userguide/connectionpostgre/|データタイプは「ODBC」を選択し、DSN名にはODBC設定時のData Source名を入力してください。<br />公式資料：<br />https://ja.sdi.ricct.com/userguide/connectionodbc/|

設定方法は下記の記事を参照：
https://qiita.com/RiCCT/items/787a41bb54277a3b26c2

### 3. マッピング設定
#### 3.1 .「新規マッピング」ボタンをクリックしてマッピング設定画面を開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/560129/a55e5ced-619b-975f-37db-4a50437b4993.png)

#### 3.2 . ソースコネクション、テーブル、ターゲットコネクション、テーブルを選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/560129/574ce8ca-5c5e-ed7c-b1a4-b91b27a6be6c.png)

|No|項目|説明|
|----|----|----|
|1|マッピング名 |マッピング名を入力、任意の名前設定できます。システムは名前の重複チェックしていないですが、管理上、ユニークの名前の設定をお勧めします。 |
|2|ソースコネクション| POSTGRE - Publicを選択|
|3|ソーステーブル | sample_tableを選択|
|4|コネクションコネクション| SNOWFLAKEを選択|
|5|コネクションテーブル | PUBLIC.SAMPLE_TABLE|
|6|カラム一覧取得 |`カラム一覧取得`ボタンをクリックしてテーブル定義明細取得|

#### 3.3 . カラムのマッピングルールを設定

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/560129/c41b4f79-2d4f-7238-2e27-4eafe1ac919d.png)

|No|項目|説明|
|----|----|----|
|7|ソースカラム|ターゲットカラムに対して、ソースデータの対応するカラムを選択します。同じカラムが存在する場合はデフォルトで自動マッピングされます。今回はデフォルト設定のままにします。<br /> ソースカラム名とターゲットカラム名が異なる場合は、対応するソースカラムを選択してください。|
|8|マッピング対象|データ連携を行うかどうかを選択します。今回は全カラムのデータを連携します。|
|9|更新方式 |`Merge`を選択。 <br />更新方式についての詳細説明は下記の資料を参照：<br />https://ja.sdi.ricct.com/userguide/mappingtarget/|

#### 3.4 . テスト実行
`マッピング実行` ボタンをクリックして、動作確認します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/560129/402e62a6-e3ac-d3ab-d234-2a6dda6b61af.png" width="400">

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/560129/74c92ae9-b366-254b-68cd-6e94bb38dd68.png)



|No|項目|説明|
|----|----|----|
|10|ステータス |実行成功の場合、マッピングを保存して、設定完了。<br />エラーが発生した場合、詳細画面でエラー内容を確認した上対応します。 |
|11|詳細アイコン| 詳細アイコンをクリックしてLOGの詳細参照できます。|


:::note info
お勧め
マッピング実行前に、ソースとターゲットの`テータ参照`ボタンをクリックして、データを確認した上実行します。マッピング成功の場合、もう一度ターゲットのデータを確認して、結果は期待通りかどうかを判断します。
:::

マッピング実行前：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/560129/d8f502be-c22b-aaea-39e2-b51a6e4a6c18.png)

マッピング実行後：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/560129/b356ccd5-2d53-5d03-2322-3104a4ed5a6d.png)

データが同期されていることを確認できました。

#### 3.5 . 保存
`保存` ボタンをクリックして、マッピング設定を保存します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/560129/d2b2b877-ed05-7a27-608f-728ba61e275d.png" width="400">


:::note info
定期的にデータ連携したい場合、スケジューラーを作成してマッピングを登録します。
スケジューラー設定につきまして、下記のページを参照してください。
https://ja.sdi.ricct.com/userguide/schedule/
:::




以上です。

[Simple Data Integrator (SDI) 実践入門](https://qiita.com/RiCCT/items/3dc109ff82546459a8b0 "Simple Data Integrator (SDI) 実践入門")

# 参考資料
[SDI日本語公式サイト](https://ja.sdi.ricct.com/ "SDI日本語公式サイト")
[SDI English Official Website](https://sdi.ricct.com/ "SDI English Official Website")
[SDIマップイング設定](https://ja.sdi.ricct.com/userguide/mapping/ "SDIマップイング設定")