メインコンテンツへスキップ

変換マップの読み方:ステージングを本番へ移すルール


    前回、インポートは「データソース → ステージング → ターゲット」の3段だと確かめました。その真ん中で、ステージングの生データを本番テーブルへ運ぶのが変換マップです。インポート・連携シリーズの2本目は、この変換マップを1レコード開いて、設定項目を1つずつ読み解きます。

    変換マップは、いわば「移し方の設計図」です。どの列を、どの項目へ、どんなルールで移すか。ここが分かると、取り込みの成否はほぼ読めるようになります。実機の User マップ(imp_user → sys_user)を教材にします。


    画像

    先に全体像です。変換マップの中には、列と項目を1対1で結ぶ「フィールドマップ」、複数列から値を作る「スクリプト」、移し方を制御する「オプション群」が入っています。この3つが協力して、ステージングの1行を本番の1レコードに仕立てます。

    このシリーズのまとめ:取り込みと連携の全体像は ServiceNowのデータ連携 全体地図 にまとめています。

    この記事は、ServiceNow の PDI(Personal Developer Instance、無料の個人検証環境)Zurich リリース・OOTB(初期設定)で確認した実測メモです。件数・状態・スクリプト内容はすべて REST と実画面で確認しました(確認日 2026-07-13)。本番環境では設定が異なります。

    User マップを開いてみる

    変換マップは sys_transform_map テーブルの1レコードです。OOTB の User マップを開くと、こんな画面になっています。


    画像

    上部に、Source table(User [imp_user])と Target table(User [sys_user])。これが「imp_user から sys_user へ移す」という宣言です。作成日は 2008-12-18 とあり、ずいぶん古くから同梱されている定番マップだと分かります。その周りに、移し方を細かく決めるチェックボックスやプルダウンが並びます。画面の上に赤い「High Risk」警告が出ているのは、これが標準同梱のレコードで、むやみに書き換えるべきでないためです。読むぶんには問題ありません。

    まず、この1画面に「変換マップの全部」が詰まっていることを押さえてください。どこへ移すか、業務ルールを走らせるか、空値をどう扱うか、スクリプトを挟むか。順番に見ます。

    マップ本体の設定項目

    User マップで実測した設定はこうでした。


    画像

    チェックボックスやプルダウンの1つ1つが、変換の挙動を変えます。特に効くのが次の4つです。

    • Run business rules(true) … 本番にレコードを作るとき、その業務ルールも走らせる

    • Enforce mandatory fields(No) … 必須項目が空でも取り込みを止めない

    • Copy empty fields(false) … ソースが空でも、既存の値を空で上書きしない

    • Run script(true) … マップ全体のスクリプトを実行する

    どれも「取り込みで本番を壊さない」ための調整弁です。順に、なぜ重要かを見ていきます。


    画像

    上は sys_transform_map テーブルの項目定義です。今見たフィールドが、テーブルの列として実在することが分かります。変換マップも1つのテーブルレコードにすぎない、という当たり前の事実が、ここで確かめられます。設定画面で並んでいたチェックボックスは、この列の値を true / false で持っているだけです。だから、REST やスクリプトからマップの設定を読み書きすることもできます。GUI の裏側が、素直なテーブルになっているのが ServiceNow の一貫した作りです。

    Run business rules:正規の入口から作る

    いちばん誤解されやすいのが Run business rules です。これが true だと、変換で sys_user にユーザーを作ったとき、sys_user に設定された業務ルール(Business Rule)も一緒に発火します。

    これは「単なるデータのコピー」ではない、ということです。人が画面からユーザーを新規作成したときと同じ処理が走ります。たとえば初期パスワードの設定、通知の送信、関連レコードの自動生成などです。つまり変換マップは、正規の入口からレコードを作る動きをします。データを裏口から突っ込むのではなく、表の玄関から入れる。だからデータの整合性が保たれます。

    逆に、何万件もの初期移行で、業務ルールを走らせたくない場面もあります。移行のたびに通知が飛んだら大惨事です。そういうときは、この Run business rules を false にして、ルールを止めたまま高速に投入する、という判断ができます。true と false で「安全に作る」と「速く入れる」を切り替えられる、という理解が大事です。

    もう1つ、Enforce mandatory fields(必須項目の強制)も、この文脈で効いてきます。User マップでは No でした。ターゲットの sys_user に必須項目があっても、それが空の行を弾かずに取り込む、という設定です。移行では「とりあえず入れて、あとで埋める」ことも多いので、既定は緩めにしてあります。逆に、必須が埋まっていないデータを絶対に入れたくないなら、これを Yes(または Mapped fields)にして、空の行を止める、という締め方もできます。Run business rules と Enforce mandatory の2つは、「本番のルールをどこまで守らせるか」を決める2枚のスイッチだと捉えると分かりやすいです。片方は処理のルール、もう片方は入力のルール。移行の性格に合わせて、この2枚を締めたり緩めたりします。

    空値の扱い:Copy empty fields

    地味ですが実務で効くのが Copy empty fields です。false のとき、ソース(imp_user)の列が空でも、ターゲット(sys_user)の既存の値は消しません。

    具体例で考えます。既存ユーザーの電話番号が入っている状態で、電話番号が空の CSV を取り込んだとします。Copy empty fields が false なら、既存の電話番号はそのまま残る。true なら、空で上書きされて消えてしまいます。うっかり空欄だらけの CSV を流して既存データを全部消す、という事故を防ぐのがこの設定です。既定は false(消さない)で、安全側に倒してあります。

    似た設定に「Create new record on empty coalesce fields」もあります。これは、突合キー(coalesce)の項目が空の行を取り込んだとき、新規レコードを作るかどうかです。User マップでは false でした。空のキーで無闇にレコードを増やさない、という配慮です。coalesce については次回、じっくり扱います。

    スクリプトで値を作る

    フィールドを1対1で対応づけるだけでは足りない場面があります。そこで登場するのが Script です。User マップの Script には、実際にこんなコードが入っていました。

    // create a user id if neccessary
    if (source.user_id.nil())
      target.user_name = source.first_name + "." + source.last_name;

    読むと素直です。「ソースの user_id が空だったら、first_name と last_name をドットでつないで user_name にする」。つまり、CSV にユーザーIDが無くても、氏名から taro.yamada のような ID を自動で組み立てているわけです。

    これはフィールドマップ(列と列の対応づけ)だけでは書けません。複数の列を組み合わせて新しい値を作るには、スクリプトが要ります。変換マップは、単純な対応づけをフィールドマップで、複雑な加工をスクリプトで、と役割を分けています。source(ステージング行)と target(作ろうとしている本番レコード)という2つの変数で、値を読み書きする、という書き方です。

    この Script の使いどころは、意外と多いのです。氏名を結合して ID を作る、日付の形式を変換する、外部システムのコード値を ServiceNow の選択肢に読み替える、フルネームを姓と名に分割する。どれも「1つの列を、そのまま別の列に入れる」だけでは足りず、途中でひと手間かかります。そのひと手間を書く場所が、このマップ本体の Script です。ただし、ここに何でも詰め込むと読みにくくなるので、単純な対応づけはフィールドマップに任せ、Script は本当に加工が要る項目だけに絞るのが良い書き方とされています。今回の User マップも、user_name の生成という1点だけをスクリプトにしていました。マップの設計思想が、この短い数行によく表れています。

    フィールドマップという中身

    マップ本体の下には、関連リスト「Field Maps(7)」があります。これが「どの列を、どの項目へ」の1対1対応の実体です。


    画像

    User マップには7件のフィールドマップがありました。Source field の列を見ると、department、email、first_name、last_name、location、phone、user_id が並びます。それぞれに Coalesce の列があり、実測では email だけ true、残り6件は false でした。この true が付いた email が、重複を防ぐ突合キーになります。ほかにも Choice action(create)、Coalesce case sensitive(大文字小文字を区別するか・false)、Date format(yyyy-MM-dd hh:mm:ss)といった、1項目ごとの細かい設定列が並んでいます。フィールドマップと coalesce は、このシリーズの次回(3本目)でまるごと扱うので、ここでは「マップの下に、列対列の対応が7件ぶら下がり、そのうち1件だけが突合キーになっている」ところまで掴んでください。

    マップを助ける道具

    変換マップの画面下には、「Related Links」として便利な操作が並んでいました。

    • Auto Map Matching Fields … ソースとターゲットで同じ名前の項目を、自動で対応づける

    • Mapping Assist … GUI で、左右の項目をドラッグして対応づける

    • Validate Coalesce Fields … coalesce の設定に問題がないか検証する

    • Transform … その場でこのマップを使って変換を実行する

    • Index Coalesce Fields … coalesce 項目に索引を張り、突合を速くする

    マップを1件ずつ手で作るのは大変なので、同名フィールドは Auto Map でまとめて対応づけ、細かいところを Mapping Assist で調整する、というのが定石です。ここも「マップは手作業だけでなく、道具で組み立てる」ことを覚えておくと、実際に触るときに迷いません。

    特に Index Coalesce Fields は、性能の面で覚えておく価値があります。coalesce は「既存レコードと突合するキー」なので、取り込みのたびに、その項目でターゲットテーブルを検索する。何万件も取り込むと、この検索が積み重なって遅くなります。coalesce 項目に索引(インデックス)を張っておけば、検索が速くなり、大量取り込みの時間が縮みます。Related Links にこの操作が用意されているのは、「coalesce を設定したら索引も張る」がセットの作法だからです。Validate Coalesce Fields は、その coalesce の設定に矛盾がないか(たとえば coalesce 項目がフィールドマップに存在するか)を事前に点検してくれます。マップを作ったら、この2つで検証と最適化をしておく、というのが手堅い進め方です。

    一覧で全体を俯瞰する

    最後に、マップの一覧に戻ります。


    画像

    14件の変換マップが、Source table と Target table の対応で並んでいます。User だけでなく、Location(imp_location → cmn_location)、Computer(imp_computer → cmdb_ci_computer)、Notification(imp_notification → incident)など。どのマップも、今回 User で見たのと同じ設定項目を持っています。1つの読み方を覚えれば、残り13件も同じ目で読めます。

    面白いのは、同じ imp_user のようなステージングに対して、複数の変換マップをぶら下げられる点です。たとえば「1つの CSV から、ユーザーを sys_user に作りつつ、同じ人の所属情報を別テーブルにも入れる」といった構成が組める。そのとき Order(実行順)が効いてきます。順序を決めておけば、先にユーザーを作ってから、そのユーザーを参照する所属情報を作る、という依存関係も守れる。1本の取り込みが、複数のマップを通って複数のテーブルへ枝分かれする。この柔軟さは、変換マップがステージングから独立した「移し方」のレコードだからこそ実現できます。取り込み口(データソース)と移し方(変換マップ)を分けている設計が、ここでも活きています。

    変換スクリプトという別レイヤー

    なお、マップ本体の Script とは別に、sys_transform_script という独立したテーブルもあります。実測で12件ありました。


    画像

    こちらは「変換のこのタイミングで動く」という、イベント単位のスクリプトです。onBefore(各行の変換前)、onAfter(変換後)、onComplete(全部終わったあと)などのタイミングを指定できます。マップ本体の Script が「フィールド値の生成」なら、こちらは「変換処理の割り込み」です。この使い分けは、シリーズ後半の変換スクリプト回で詳しく扱います。

    整理すると、変換マップの中には3つの「スクリプトの居場所」があります。1つはマップ本体の Script(フィールド値をその場で作る)。もう1つは、この sys_transform_script(変換の各タイミングに割り込む)。そして、フィールドマップ1件ごとにも小さなスクリプトを書けます(次回)。どこに書くかで、動くタイミングと範囲が変わります。同じ「スクリプト」でも役割が違うので、混同しないことが、変換をトラブルなく組む第一歩になります。

    確認導線

    実機で開くときの入口です(URL形式は list.do 規約に基づきます。実クリック確認は今回の範囲外です)。

    • 変換マップ一覧 … sys_transform_map_list.do

    • 変換マップ1件 … sys_transform_map.do?sys_id=...

    • フィールドマップ … sys_transform_entry_list.do

    • 変換スクリプト … sys_transform_script_list.do

    まとめ

    変換マップは、ステージングを本番へ移すための「設計図」でした。Source と Target を宣言し、Run business rules で正規の入口から作り、Copy empty fields で既存データを守り、必要なら Script で値を組み立てる。1つのレコードに、移し方のすべてが詰まっています。今回 User マップで読んだ設定は、14件どのマップにも共通する読み方です。

    実機で新しい取り込みを設計するときも、見る順番は同じです。まず Source と Target で「どこからどこへ」を決めます。次に Run business rules と Enforce mandatory で「本番のルールをどこまで守らせるか」を選ぶ。Copy empty fields で「既存データを守るか」を確認し、最後に、フィールドマップと Script で「1項目ずつどう移すか」を詰めます。この順で埋めていけば、抜け漏れなくマップを組めます。設定項目が多く見えても、役割で束ねれば数は多くありません。

    次回は、この下にぶら下がるフィールドマップと coalesce(重複を防ぐ突合キー)を、User の単一キーと Location の複合キーの対比で詳しく見ていきます。

    その他、実機で確認した記録

    用語

    • 変換マップ(sys_transform_map) … ステージングの列を本番テーブルへ対応づけるルール

    • Run business rules … 変換時に本番テーブルの業務ルールも走らせる設定

    • Copy empty fields … ソースが空のとき既存値を上書きするか(false=守る)

    • フィールドマップ(sys_transform_entry) … 列と項目の1対1対応

    • Script(マップ本体) … 複数列を組み合わせて値を生成するスクリプト

    自分の環境で確認するときのURL

    自分のインスタンス名を先頭に付けると、同じ画面が開けます。

    • /sys_transform_map_list.do(変換マップ14件)

    • /sys_transform_map.do?sys_id=...(1マップの設定項目)

    • /sys_transform_entry_list.do(フィールドマップ)

    • /sys_transform_script_list.do(変換スクリプト12件)

    実測の要点(再掲)

    • User マップ: Run business rules=true / Enforce mandatory=No / Copy empty fields=false / Run script=true / Order=100

    • Script: user_id が空なら first_name.last_name を user_name に生成

    • Field Maps 7件(うち email が coalesce)/変換スクリプト 12件(onBefore 8 が主)

    検証範囲とおことわり

    • この記事のフィールド値・スクリプト内容・関連リスト件数は、PDI(Zurich / OOTB)の実測です。

    • 実際に変換を実行した結果(生成レコード・スクリプトの実行挙動)は、sys_import_set が0件のため未確認(検証範囲外)です。

    • User マップは「High Risk」の標準レコードで、実機では原則書き換えません。

    • list.do のURL形式は規約に基づくもので、実クリック確認は今回の範囲外です。

    参考リンク

     
     
    ServiceNowのPDI(Personal Developer Instance)を実機で観察して、Noteに記事を書いています 実装・運用・教育の現場視点で淡々と記録中です リクエストがあればその記事も書きます 個人の観察日記です

    あなたへのおすすめ