Salesforce のデータを DWH と連携しておいて!!と言われた時に読む記事

## 概要

Salesforce と DWH のデータ連携の実施方法を整理します。

## 本記事のスコープ

Salesforce のオブジェクトを REST API 経由でデータの連携（Salesforce からのデータ読み込みとSalesforce へのデータ書き込み）を実施するための基本的な情報の整理と実施ステップを整理します。

Salesforce のインテグレーションの`バッチデータの同期`を行います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/617f8225-b977-872a-dddd-37923aa8d9d6.png)

引用元：[パターンの概要 | インテグレーションのパターンと実践 | Salesforce Developers](https://developer.salesforce.com/docs/atlas.ja-jp.248.0.integration_patterns_and_practices.meta/integration_patterns_and_practices/integ_pat_pat_summary.htm)

Salesforce REST API と Salesforce Bulk API 2.0 経由で外部 ETL ツールにてデータ連携することを対象とし、`バッチデータの同期`のソリューションとして記述されている Salesforce 変更データキャプチャ機能は対象としません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/9f9825b6-4d7b-674e-1a55-ef50b588ff2a.png)

引用元：[バッチデータの同期 | インテグレーションのパターンと実践 | Salesforce Developers](https://developer.salesforce.com/docs/atlas.ja-jp.248.0.integration_patterns_and_practices.meta/integration_patterns_and_practices/integ_pat_batch_data_sync.htm)

## 想定ロール

| #    | ロール            | 概要                              |
| ---- | ----------------- | --------------------------------- |
| 1    | Salesforce 管理者 | Salesforce システム管理者。       |
| 2    | データエンジニア  | Salesforce と DWH とのデータ連携の実施者。 |
| 3    | データ利用者エンジニア  | Salesforce のデータ利用者。 |

## データ連携に向けたステップ

### 1. データエンジニアが Salesforce を知る

データエンジニアが Salesforce とのデータ連携をスムーズに進めるために、 Salesforce の概念や用語を知ることが重要です。Salesforce には検証環境と学習コンテンツが無償で提供されている Trailhead を利用することがおすすめです。データエンジニアに Salesforce に関する知識がない場合には、Salesforce 認定アソシエイト資格試験の講座を受講することがおすすめです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/cf1adc83-56d4-1f9d-71fe-c7f935c88715.png)

引用元：[Trailhead | 楽しく学ぶ方法 (salesforce.com)](https://trailhead.salesforce.com/ja/)

Salesforce サクセスナビというサイト上のコンテンツもとても有益です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/79f763cc-d8bb-26ba-c44b-9c1a7f54652d.png)

引用元：[はじめてガイド｜Salesforce サクセスナビ](https://successjp.salesforce.com/salescloud/learn-how-to-use)

Salesforce の概要を把握後は、Trailhead にて提供されている Salesforce の REST API に関するトレーニングが参考となります。

- [Quick Start: Connect Postman to Salesforce | Salesforce Trailhead](https://trailhead.salesforce.com/ja/content/learn/projects/quick-start-connect-postman-to-salesforce)
- [プラットフォーム API の基本 | Salesforce Trailhead](https://trailhead.salesforce.com/ja/content/learn/modules/api_basics)

YouTube に視聴できる Salesforce Developers Japan が提供している下記の動画も参考になります。

- [Salesforce 認定Integration アーキテクト試験のポイント (youtube.com)](https://www.youtube.com/watch?v=Lq2HKEwD60o)
- [Salesforceのデータ管理をマスターしよう！〜 認定データアーキテクト試験のポイント (youtube.com)](https://www.youtube.com/watch?v=MfS8gxmsDCI)
- [【機能紹介】Salesforceの共有設定をマスターしよう！ 〜 Sharing & Visibility - YouTube](https://www.youtube.com/watch?v=6VVZ5axt9vs)

### 2. データエンジニアがデータ連携の要件を検討

#### 検討事項

- データ連携対象のオブジェクト、項目、及び、レポート
- 利用する API、データ量、連携頻度、及び、同時 API 利用数
- データ連携ツールの仕様

#### データ連携対象のオブジェクト、項目、及び、レポート

Salsefoce では、オブジェクトレベル、項目レベル、及び、レコードレベルでデータセキュリティが設定されているため、データ連携対象のオブジェクト、項目、レコードを定義することが重要です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/05070766-0d8f-a4a7-f392-598ece4ba52c.png)

引用元：[Salesforceの用語を理解して、使う人にあった画面の設定を行う｜Sales Cloud｜Salesforce サクセスナビ](https://successjp.salesforce.com/article/NAI-000131)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/648cd6ed-e003-e291-48c9-ed182e609701.png)

引用元：[部署やチーム毎にみることができるデータを設定する｜Sales Cloud｜Salesforce サクセスナビ](https://successjp.salesforce.com/article/NAI-000106)

レポートの項目によりデータ連携することも可能であり、その際に必要となる Report ID を下記のようなレポートで確認することがおすすめです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/5e10b4f9-177e-03fb-de46-0781dbe0b10d.png)

引用元：[Salesforce にて作成されているレポート の Report ID 等の情報を一覧化したレポートを作成する方法 #Salesforce - Qiita](https://qiita.com/manabian/items/ceaef5638f36e512c962)

#### 利用する API、データ量、連携頻度、及び、同時 API 利用数

Saleforce における下記の API の利用制限を考慮して利用する API、データ量、連携頻度、及び、同時 API 利用数（実行時間が 20　秒以上の API の同時実行数）を検討する必要があります。

1. 同時 API 要求数
2. 24 時間あたりの合計 API 要求合計数

Salseforce 上に作成する接続アプリにて利用できる API のスコープを定義するために、利用する API を検討します。基本的には`API を使用してユーザーデータを管理 (api)`というスコープで十分な可能性がありますが、その他の API を利用する場合には必要なスコープを検討してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/4d3d5673-74cc-50c8-1b22-e10d7ad01322.png)

引用元：[OAuth トークンおよび範囲 (salesforce.com)](https://help.salesforce.com/s/articleView?id=sf.remoteaccess_oauth_tokens_scopes.htm&type=5)

データ操作のパターンとしては下記のものがあり、どのように実装するかを検討する必要があります。

- Salesforce からのデータ読み込み
    - オブジェクト、あるいは、レポートからデータ読み込み
- Salesforce へのデータ書き込み
    - INSERT
    - UPSERT
    - UPDATE
    - DELETE

Salesforce REST API と Salesforce Bulk API 2.0 の使い分ける基準として 2000 レコードの目安が提示されていますが、 DWH との連携を実施する場合には多数のオブジェクトから大量のレコードを抽出するため  Salesforce Bulk API 2.0 を優先的に利用することが良さそうです。

> Bulk API 2.0 の候補として、2,000 件を超えるレコードを含むデータ操作をお勧めします。これにより、Bulk フレームワークを使用する非同期ワークフローの準備、実行、管理を正常に行うことができます。2,000 レコード以下のジョブでは、REST (Composite など) または SOAP による「一括」の同期呼び出しを行うことをお勧めします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/45ae1421-f4c2-fd1f-ba55-059b3d5b4472.png)

引用元：[Bulk API 2.0 と Bulk API の概要 | Bulk API 2.0 および Bulk API 開発者ガイド | Salesforce Developers](https://developer.salesforce.com/docs/atlas.ja-jp.api_asynch.meta/api_asynch/asynch_api_intro.htm)

#### データ連携ツールの仕様

利用を想定しているデータ連携ツールにおける Salesforce への認証方法とネットワーク経路を確認します。

Salesforce への認証方法としては主に下記の方法があり、データ連携ツールにより自動化する場合には 1 を選択することが多いようです。

1. [サーバー間インテグレーション用の OAuth 2.0 クライアントログイン情報フロー (salesforce.com)](https://help.salesforce.com/s/articleView?id=sf.remoteaccess_oauth_client_credentials_flow.htm&type=5)
2. [特別なシナリオの OAuth 2.0 ユーザー名パスワードフロー (salesforce.com)](https://help.salesforce.com/s/articleView?id=sf.remoteaccess_oauth_username_password_flow.htm&type=5)
3. [OAuth 2.0 Web Server Flow for Web App Integration (salesforce.com)](https://help.salesforce.com/s/articleView?id=sf.remoteaccess_oauth_web_server_flow.htm&type=5)

2 の方法の利用方法が記事としてよく投稿されていますが、現時点では非推奨の方法となっているようです。

> 重要 セキュリティを強化するために、ユーザー名パスワードフローの代わりに、コード交換の証明鍵 (PKCE) を使用する OAuth 2.0 Web サーバーフロー、または OAuth 2.0 クライアントログイン情報フローを使用することをお勧めします。

引用元：[特別なシナリオの OAuth 2.0 ユーザー名パスワードフロー (salesforce.com)](https://help.salesforce.com/s/articleView?id=sf.remoteaccess_oauth_username_password_flow.htm&type=5)

Salesforceでは、ユーザーや接続アプリに対してIP制限を設定できるため、Salesforceへのネットワーク経路を慎重に検討することが重要です。SaaS型のデータ連携ツールを利用する場合、ネットワーク経路が他のユーザーと共有されることが多いため、接続情報が流出した際にそのツールからデータが外部に漏洩するリスクを許容できるかどうかを確認する必要があります。

### 3. Saleforce 管理者にデータ連携方法のすり合わせ

#### 検討事項

- 連携方針の認識合わせ
- 統合ユーザーと接続アプリの作成依頼

#### 連携方針の認識合わせ

検討内容をデータエンジニアが Salesforce 管理者に説明し、連携方針の認識合わせを実施します。

#### インテグレーションユーザー、接続アプリ、及び、Sandbox 環境の作成依頼

連携方針に基づいて、インテグレーションユーザーと接続アプリの作成を依頼します。

### 4. データ連携アプリケーションの設計と開発

#### 実装方針

##### 基本的な検討事項

- 操作可能なレコードと項目の確認
- 差分連携方法の確立
- DELETE を考慮した Salesforce からの読み込み

##### 操作可能なレコードと項目の確認

Salesforce 管理者から提供された接続情報により、想定通りにオブジェクト、レコード、及び、レコードを取得できることを確認します。レコードの過不足については、データ利用者の判断が必要になる場合があります。

##### 差分連携方法の確立

Salesforce から読み込む場合に差分連携を実施する場合には、オブジェクトのシステム列である`SystemModStamp`列を基準列（ウォーターマーク列）として利用できそうです。

![](https://storage.googleapis.com/zenn-user-upload/e86f1900c908-20240623.png)

引用元：[システム項目 | Salesforce プラットフォームのオブジェクトリファレンス | Salesforce Developers](https://developer.salesforce.com/docs/atlas.ja-jp.object_reference.meta/object_reference/system_fields.htm)

Salesforce のオブジェクトにはデフォルトで下記の列にインデックスが設定されている旨の記載があるため、`SystemModStamp`列でフィルタリングしても性能上は問題なさそうです。

![](https://storage.googleapis.com/zenn-user-upload/4d3b74d5184d-20240623.png)

引用元：[インデックス | 大量のデータを使用するリリースのベストプラクティス | Salesforce Developers](https://developer.salesforce.com/docs/atlas.ja-jp.salesforce_large_data_volumes_bp.meta/salesforce_large_data_volumes_bp/ldv_deployments_infrastructure_indexes.htm)

##### DELETE を考慮した Salesforce からの読み込み

Salesforce にて DELETE されたレコードは一定期間保持されてから物理削除されるため、定期的にデータ連携を実施して DELETE されたレコード（IsDeleted = True）を DWH に反映する必要があります。Salesforce Bulk API 2.0 ではqueryALL を指定することで、 DELETE されたレコードも連携されます。

> レコードを削除しても Salesforce から完全に削除されるわけではなく、復元できるように 15 日間はごみ箱に置かれます。

引用元：[レコードの削除 | Apex 開発者ガイド | Salesforce Developers](https://developer.salesforce.com/docs/atlas.ja-jp.apexcode.meta/apexcode/langCon_apex_dml_examples_delete.htm)

![](https://storage.googleapis.com/zenn-user-upload/e86f1900c908-20240623.png)

引用元：[システム項目 | Salesforce プラットフォームのオブジェクトリファレンス | Salesforce Developers](https://developer.salesforce.com/docs/atlas.ja-jp.object_reference.meta/object_reference/system_fields.htm)

#### Azure Data Factory で実装する方法

##### データ連携パターンの検討

データ連携パターンとして、下記の記事にて整理しています。Salesforce からのデータ読み込み方法が Salesforce をソースとした場合の記事であり、とSalesforce へのデータ書き込みが Salesforce をシンクとした場合の記事です。

- [Azure Data Factory にて Salesforce をソースとした場合のデータ連携パターン #データエンジニアリング - Qiita](https://qiita.com/manabian/items/8c0079b793b85859f1d7)
- [Azure Data Factory にて Salesforce をシンクとした場合のデータ連携パターン #データエンジニアリング - Qiita](https://qiita.com/manabian/items/51bf3bb423a22315ae6d)

### 5. データ連携アプリケーションの運用

#### 検討事項

- API の利用状況の監視
- Hard Delete したレコードの対応

#### API の利用状況の監視

API を想定以上に利用していないことを確認します。

#### Hard Delete したレコードの対応

レコードが Hard Delete された場合には、 DWH に反映する必要があります。 Hard Delete を実施する場合には非定常オペレーションであることが予測されるため、データエンジニアも例外的な対応が必要となる場合があります。

## 関連情報

### 用語整理

| #    | Salesforce の用語 | 概要                                                      | 備考 |
| ---- | ----------------- | --------------------------------------------------------- | ---- |
| 1    | オブジェクト      | RDB におけるテーブル。                                    |      |
| 2    | レコード          | RDB におけるレコード。                                    |      |
| 3    | 項目              | RDB におけるカラム。                                      |      |
| 4    | Salesforce ID     | Salesforce が自動的に各レコードに割り当てる一意の識別子。 |      |
| 5    | 外部 ID           | Salesforce 以外のシステムで割り当てる一意の識別子。       |      |
| 6    | 標準オブジェクト     |  Salesforceにデフォルトで含まれているオブジェクト。 |      |
| 7    | カスタムオブジェクト   | ユーザーが独自に作成するオブジェクト。       |  API で利用する際には末尾に`__c`がつく。    |
| 8    | 標準項目     | Salesforceにデフォルトで含まれている項目。 |      |
| 9    | カスタム項目   | ユーザーが独自に作成する項目。       |  API で利用する際には末尾に`__c`がつく。    |

### データ統合に利用するユーザーと接続アプリ

下記の記事を参考に、データ統合を実施するインテグレーションユーザーと接続アプリを作成します。

- [インテグレーションユーザーへの API 限定アクセス権の付与 (salesforce.com)](https://help.salesforce.com/s/articleView?id=sf.integration_user.htm&type=5)
- [OAuth 2.0 クライアントログイン情報フローの接続アプリケーションの設定 (salesforce.com)](https://help.salesforce.com/s/articleView?id=sf.connected_app_client_credentials_setup.htm&type=5)

### API の利用制限

#### API の利用制限に関する概要

API 利用時には下記の制限があります。

1. 同時 API 要求数
2. 24 時間あたりの合計 API 要求合計数

#### 同時 API 要求数

20 秒以上の API 実行に対して下記のような制限があります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/6e58006d-c5df-280e-f2a1-862604aeb4a3.png)

引用元：[API 要求の制限と割り当て | Salesforce Developer の制限および割り当てクイックリファレンス | Salesforce Developers](https://developer.salesforce.com/docs/atlas.ja-jp.salesforce_app_limits_cheatsheet.meta/salesforce_app_limits_cheatsheet/salesforce_app_limits_platform_api.htm)

#### 24 時間あたりの合計 API 要求合計数

API ごとに 24 時間あたりの合計 API 要求合計数の制限があります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/8268866c-dfac-830a-356b-68a4e60da3c6.png)

引用元：[API 要求の制限と割り当て | Salesforce Developer の制限および割り当てクイックリファレンス | Salesforce Developers](https://developer.salesforce.com/docs/atlas.ja-jp.salesforce_app_limits_cheatsheet.meta/salesforce_app_limits_cheatsheet/salesforce_app_limits_platform_api.htm)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/e9b0a537-881f-e4a9-0ca1-0307337ad5f1.png)

引用元：[Bulk API および Bulk API 2.0 の制限および割り当て | Salesforce Developer の制限および割り当てクイックリファレンス | Salesforce Developers](https://developer.salesforce.com/docs/atlas.ja-jp.salesforce_app_limits_cheatsheet.meta/salesforce_app_limits_cheatsheet/salesforce_app_limits_platform_bulkapi.htm)