こんにちは
最近珍しくSalesforceを触っています。(FLECTではSalesforce素人の僕の方が少数派なんですが。。。)
案件需要として「RDBMSのデータを定期的にSalesforceに同期する」という要件があるのでそれが汎用的にできるツールを作成しているのです。
で、そのバックロジックとしてはBulk APIを使うのでざっと検証したその動作を書きとめておきたいと思います。
★Bulk APIとは?
大雑把に言ってしまえばCSVで作成したデータを一気にSalesforceに取り込むためのAPIです。
他にもXML形式で取り込めたりクエリでSELECTした大量のCSVデータをダウンロードしたりもできますがここでは触れません。
Salesforce識者の方にはDataLoaderが裏で使用しているAPIというのがわかりやすいでしょうか。 (といいつつ、DataLoaderはデフォルトではSOAP APIを使用する設定になっており設定変更しないとBulkAPIは使われませんが。)
★とりあえず使ってみる
BulkAPIの使い方自体はドキュメントを読めばなんとなくわかります。
簡単にまとめると
- WebAPIのOpenJOBメソッドでジョブを開始
- WebAPIのAddBatchメソッドでCSVファイルをPOST(複数回可)
- WebAPIのCloseJOBメソッドでジョブを完了
ジョブの実行自体は非同期なのでAddBatchがリターンした時にはまだデータの更新は完了していません。ただしAddBatch自体がかなり重たいメソッドのようで7MB程度のファイルのアップロードで2分前後の時間がかかっています。
AddBatchからリターンした後にはまだデータ更新の途中であってもCloseJobメソッドを実行してしまって構いません。それでデータ更新が中断されるようなことはなく、データ更新終了時に自動的にクローズされます。
CloseJobを実行しなかった場合、ジョブは一週間オープンしたまま残ります。(とドキュメントに書いてあります。)
クローズした後でもJobのステータスは確認できるのでAddBatchが終わったらさっさとクローズしてしまった方が良いです。
★ジョブの実行結果の確認
ジョブのステータスの確認はWebAPIでもできますが、Salesforceの画面上で行う方が簡単です。
設定 > 管理者設定 > 監視 > 一括データ読み込みジョブ
の項にジョブの状況確認画面があります。
この画面では処理に成功したレコードが何件あるか、失敗したレコードは何件あるかと言ったサマリ的な情報を確認できる他にバッチの「結果を表示」を実行することで処理を行った全レコードについて
- レコードのID
- 処理に成功したかどうか
- 処理内容はInsertかUpdateか
- エラーがあった場合そのエラーメッセージ
が、CSV形式で確認できます。
★エラー時の動作検証
さて、このBulkAPI。正常ケースは特に迷うところはありません。
API実行しました。データ入りました。以上終わり。です。
ここではガバナ制限やレコードデータの不正などエラーケースについてどのような動作をするかを検証していきたいと思います。
ちなみにテストはDeveloperEditionを使用して1万5000件くらいのデータを使用して行いましたが、その環境は現在こんなことになっています。
ストレージ使用量600%です。(^^;;;
BulkAPIでもディスク容量のチェックはもちろん行われますが、ジョブの実行中はしばらく容量超過に気が付かないようで、100%を越えてもしばらくはデータがInsertできます。
バッチの途中からでもエラー(ストレージ超過)になることはあるので、どういうタイミングでチェックが行われているのかは謎ですが、これはそういうもののようです。
まぁそうでなければ今回のテストはほとんど実行できなかったので良いのですが。(^^;;
ちなみにこれだけ容量を超過していてもBulkでのUPDATEは問題なく実行できます。(INSERTはもちろんエラーになりますが。)
以下、今回チェックしたエラー時の動作です。検証はBulk APIのドキュメントにあるLimitsを超過したケースといくつかのレコードエラーについて実施しました。
AddBatchのファイルサイズが10MBを越えていた場合
この場合、AddBatchのレスポンスとしてHttp status「400 BadRequest」が返ってきます。当然バッチはジョブに追加されませんし実行もされません。
CSVに1万1行以上のレコードがあった場合
AddBatchには成功し、バッチジョブも実行されます。ただし、1万行を越えたレコードについては無視されて処理が実行されません。
実行結果を確認すると、「失敗したバッチ数」はカウントアップされていますが、「レコードの失敗」には無視されたレコードはカウントされません。
CSVに1000万文字以上の文字があった場合
未テストです。日本語データを含む場合1000万文字は確実に10MBを超えると思われるのであまり意味がありません。
1フィールドに32000文字以上の文字があった場合
AddBatchには成功しますが、バッチ処理全体が実行されません。例えば1行だけにエラー行があって他のレコードには問題がない場合であっても1行も処理は実行されません。
エラーのない行については処理してくれても良さそうなものですが。。。LongTextの上限が32768文字であるにも関わらずここでの制限が32000文字であることも謎です。
CSVに5000フィールド以上あった場合
未テストです。。。(--
ネタとしてMetadataAPIで5000フィールド作ろうかとも思いましたがやっぱり面倒なので。(^^;;;
BulkうんぬんよりもSalesforceの設定画面の方が先に限界を迎えそうな気がします。
1レコードに40万文字以上あった場合
これも未テストです。。。(--
一般的なスキーマでテストしようとすると先に1フィールド32000文字の制限に引っ掛かると思うので。
おそらく結果は1フィールドの超過の場合と同じだろうと予想しています。
テキスト項目サイズ超過(256文字)のレコードがある場合
そのレコードだけがエラーになります。
エラー内容はジョブの確認画面からダウンロードできる結果CSVで行単位に確認できます。
選択項目に未定義の選択値がある場合
エラーとはならずそのまま更新されます。
予想としてはエラーになると思ったんですが、識者に確認するとこれはそういうものらしいです。。(--
メール項目に不正なメールアドレスがある場合
そのレコードだけがエラーになります。
エラー内容はテキスト項目サイズ超過の場合と同じように確認できます。
基本的にはレコードのエラーはその行だけがエラーになると考えて良さそうです。
(選択項目の挙動がイマイチ納得いきませんが。。。)
★Bulk APIの運用方法
ここまでの結果から、なんとなくCSVを作成してとりあえず投げてみて結果はジョブ確認画面で確認。で十分な気がします。
レコード数超過だけは半端な結果になるのでCSV作成時に10000行を越えないことだけは注意した方が良いですが、それ以外のケースはエラー確認後にCSVを修正してリトライで十分な気がします。
レコードの項目エラーについてもSalesforce側でちゃんとチェックしてくれるので、事前にチェックする必要性はあまり感じません。(メールアドレスなんかは事前にチェックしたとしてもチェック内容が同じかどうかなんてわかりませんし。。。)
□□□□
そんな感じでRDBからのSELECT結果をなんとなくBulkで突っ込むツールがもうじき完成します。(^^;