メインコンテンツへスキップ
見出し画像

ServiceNowの外部データ取込はなぜ2段階? Import SetとTransform Mapを実機で追う


    CSVやJDBCで読み込んだデータが、ServiceNowのsys_userやcmdb_ciにいきなり入らないのはなぜでしょうか。外部データ取込は、データをいったん受ける「箱」のImport Setと、そこから実テーブルへ流し込む「ルール」のTransform Mapという2段階に分かれているためです。Zurich PDIでImport Set・Transform Map・Field Mapの中身と件数を実機で確認しました。

    検証環境:Zurich PDI / OOTB / 2026-08-08 確認

    結論:外部データが2段階を経てターゲットに入る理由

    先に全体像です。

    • 外部データ取込は、①ステージング(Import Set)→②変換(Transform Map/Field Map)→ターゲットへのinsertまたはupdateという2段階の処理に分かれています。

    • 今回のPDIでは、Import Setと取込行は0件でした。取込を実行するたびに動的に作られるテーブルのため、取込を1回も実行していないこのPDIには残っていません。一方でTransform Map(14件)とField Map(119件)は、常駐する設定として最初から入っていました。

    • 「取り込んだのに増えない」「重複する」という症状の多くは、coalesce(重複判定キー)の設定に理由があります。Field Map 119件のうちcoalesce=trueは14件でした。


    画像

    上の図がその2段階です。外部データはまずImport Setという箱に受け止められ、Transform MapとField Mapという変換ルールを経て、最後にターゲットの実テーブルへinsertまたはupdateされます。箱の中身(Import Set・取込行)は今回0件、変換ルール側(Transform Map・Field Map)は常に存在するという対照的な状態でした。この対照が、後述する「実機で気づいたこと」につながります。

    なぜテーブルに直接入れず、いったん受けるのか

    Import Set(インポートセット)は、外部データをServiceNowに取り込むときの「いったん受ける箱」です。CSVやExcel、JDBC(データベース直結)から読み込んだデータは、まず取込専用のステージングテーブルに格納されます。この取込の単位を管理するのがsys_import_setというテーブルです。データソースの種類ごとの違い(File・JDBC・LDAP・OIDC)は、データソースの種類:File・JDBC・LDAP・OIDCで個別に確認しています。

    Transform Map(変換マップ)は、ステージングに溜まったデータを「どの実テーブルの、どの列に、どう入れるか」を定義するマッピングです。ソース列とターゲット列の対応づけを1本ずつ持ち、それらをまとめて1つの変換ルールにします。

    外部データが直接sys_userなどに入らず、いったんステージングを挟む理由は、生データと変換後の実テーブルを切り離して扱うためです。生データはあとから見直せますし、変換ルールは別に管理・配布できます。全体の位置づけは、公式ドキュメントのImport sets key conceptsにも整理されています。

    ステージング側は「箱」と「取込行」の2層でできている

    結論を先に。ステージング側には性質の違う2種類のテーブルが関わります。ひとつは取込ジョブを管理するsys_import_set、もうひとつは生データを溜める動的な取込テーブルです。


    画像

    sys_import_set(Import Set)は「取込ジョブ1回ぶん」を表す管理レコードです。今回のPDIで確認した主なフィールドは、state(状態)・mode(同期・非同期)・data_source(→sys_data_source)・table_nameでした。stateはloading(読込中)→loaded(読込完了)→processed(変換済み)と進み、途中でcancelled(中止)になることもあります。modeはasynchronous(非同期)が既定で、synchronous(同期)も選べます。

    もうひとつが、取込先ごとに作られる動的な取込テーブルです。取り込んだ生データの行(取込行)を実際に保持するテーブルで、sys_import_setのtable_nameにその名前が入ります。OOTBの変換マップを見ると、ソース側のテーブル名はimp_user/imp_computer/oidc_okta_importのように「取込用ステージング」の命名になっていました。この動的テーブルの内部スキーマは環境依存のため、本記事では構造上の位置づけにとどめます。

    App Navigatorでは、取込の入口は次の場所にあります(先頭の<YourInstance>は自分のインスタンスに置き換えてください)。

    System Import Sets > Load Data
    Import Set 一覧 : https://<YourInstance>/sys_import_set_list.do


    画像

    変換ルールはTransform MapとField Mapの親子構造

    結論を先に。変換ルールは「親」と「子」の2テーブルでできています。親はTransform Map(1件の変換ルール本体)、子はField Map(列ごとの対応を複数本持つ)です。今回確認したPDIでは、Transform Map(sys_transform_map)もField Map(sys_transform_entry)も同じ性質でした。どちらもApplication File(sys_metadata)を継承するテーブルです。更新セットで運べるアプリケーション構成という位置づけで、取込のたびに作られるランタイムのImport Setとは性質が異なります。仕組みの詳細は公式ドキュメントのTransform mapsでも説明されています。


    画像

    Transform Map(sys_transform_map)は、変換ルールの「親」です。name(名称)、source_table(取込元)、target_table(取込先)を持ち、source_tableとtarget_tableは必須です。そのほかactive(有効)、order(複数マップの実行順)、run_business_rules(取込時にターゲットのBusiness Ruleを動かすか)などの設定を持ちます。

    Field                                       Label                     Type / default      役割
    ----------------------------------------------------------------------------------------------
    name                                        Name                      String(必須)      変換マップの名称
    source_table                                Source table              table_name(必須)  取込元(import テーブル)
    target_table                                Target table              table_name(必須)  取込先の実テーブル
    active                                      Active                    Boolean / true      有効・無効
    order                                       Order                     Integer / 100       複数マップ時の実行順
    run_business_rules                          Run business rules        Boolean / true      取込時に対象テーブルの BR を動かすか
    enforce_mandatory_fields                    Enforce mandatory fields  String / "No"       必須項目の強制
    copy_empty_fields                           Copy empty fields         Boolean / false     空値も上書きコピーするか
    create_new_record_on_empty_coalesce_fields  (同左)                  Boolean / false     coalesce 値が空のとき新規作成するか
    run_script                                  Run script                Boolean / false     変換スクリプトを動かすか
    script                                      Script                    script_plain        行単位の変換スクリプト

    Field Map(sys_transform_entry)は、その「子」です。1本が「ソース列→ターゲット列」1組の対応を表します。mapフィールドで親のTransform Mapを参照し、source_fieldとtarget_fieldで列の対応を持ちます。今回のPDIではField Mapは119件あり、これは14件のTransform Mapにぶら下がる対応づけの合計です。

    区分        項目                               値・型                                    意味
    ---------------------------------------------------------------------------------------------
    Field Map   map                                Reference → sys_transform_map             所属する変換マップ
    Field Map   source_field → target_field        field_name                                ソース列→ターゲット列の対応
    Field Map   coalesce                           Boolean / false                           重複判定キーにするか
    Field Map   coalesce_empty_fields              Boolean / false                           coalesce 値が空でも判定に使うか
    Field Map   choice_action                      create / reject / ignore(既定 create)   選択肢に無い値が来たときの動作
    Field Map   use_source_script / source_script  Boolean / script                          列を計算で埋める
    Import Set  state                              loading → loaded → processed / cancelled  取込ジョブの状態
    Import Set  mode                               asynchronous(既定)/ synchronous         取込の同期・非同期
    Import Set  table_name                         table_name                                取込先の動的 import テーブル名

    Transform Map一覧は、次のURLで確認できます。

    https://<YourInstance>/sys_transform_map_list.do

    OOTBの14個の変換マップから読み取れること

    OOTBの変換マップは、ソースとターゲットの組み合わせを見ると役割がよく分かります。

    変換マップ名                        source_table              target_table
    --------------------------------------------------------------------------
    User                                imp_user                  sys_user
    Location                            imp_location              cmn_location
    Computer                            imp_computer              cmdb_ci_computer
    Notification                        imp_notification          incident
    LDAP User Import                    ldap_import               sys_user
    LDAP Group Import                   ldap_group_import         sys_user_group
    Okta Example                        oidc_okta_import          sys_user
    Azure AD Example                    oidc_azure_ad_import      sys_user
    Auth0 Example                       oidc_auth0_import         sys_user
    Google Example                      oidc_google_import        sys_user
    ADFS Example                        oidc_adfs_import          sys_user
    Employee Job Profile Transform Map  sn_employee_position_stg  sn_employee_position
    Goal Import                         imp_sn_gf_goal            sn_gf_goal
    Target Import                       imp_sn_gf_goal_target     sn_gf_goal_target

    今回のPDIには14件の変換マップがありました。中心となるのはUser(imp_user→sys_user)とComputer(imp_computer→cmdb_ci_computer)です。これにLocation(imp_location→cmn_location)とNotification(imp_notification→incident)が加わり、代表的な4件になります。ここにLDAP/Okta/Azure ADなどのSSO連携用も加わります。いずれもactive=trueです。ターゲットはsys_user・cmdb_ci_computer・cmn_location・incidentなど、おなじみの実テーブルでした。SSO連携用が5件を占めている点を見ると、外部データ取込という機能は「一括データ移行」だけでなく「ユーザー認証連携の下ごしらえ」としても使われる設計だと分かります。

    「重複する」「入らない」の正体はcoalesceにある

    結論から。coalesceはField Map(sys_transform_entry)側のフラグで、その列を「重複判定キー」として使うかどうかを表します。仕組みは公式ドキュメントのUpdating records using coalesceでも説明されています。


    画像

    変換時、coalesce=trueが付いた列の値を使い、ターゲットテーブルに同じ値のレコードがないか探します。見つかれば既存レコードをupdate(上書き)し、見つからなければ新規にinsertします。coalesceが「同じデータかどうか」を判定する仕組みです。

    今回のPDIでは、Field Map 119件のうちcoalesce=trueは14件でした。例としてUserマップ(imp_user→sys_user)のField Mapを見てみます。対応するフィールドはuser_id→user_name・first_name・last_name・email・phone・department・locationの7組でした。このうちcoalesce=trueが付いていたのはemailだけです。同じemailの利用者がいれば既存を更新し、いなければ新規作成する、という挙動につながる構造です。

    ここから、よくある2つの症状は次のように読めます。

    • 重複する:coalesceキーが未設定、またはソース側の値がぶれている(表記ゆれ・空値など)と、毎回「既存なし」と判定されてinsertされ続け、重複します。

    • 入らない/上書きされる:coalesceキーの値が既存と一致するとupdateになるため、新規として増えません。意図せず別レコードを上書きしている場合もあります。

    関連する設定もあります。ひとつはField Mapのcoalesce_empty_fields(coalesce値が空でも判定に使うか)です。もうひとつはTransform Mapのcreate_new_record_on_empty_coalesce_fields(coalesce値が空のとき新規を作るか)です。今回のPDIでは、これらの既定はいずれもfalseでした。

    coalesceが付いたField Mapは、次のURLで一覧できます。

    https://<YourInstance>/sys_transform_entry_list.do?sysparm_query=coalesce=true


    画像

    選択肢にない値が来たときはどうなるのか(choice_actionとsource_script)

    Field Mapには、単純な列対応のほかにも、取込時の細かな振る舞いを決める設定があります。今回確認したPDIで目立つものは次のとおりです。

    • choice_action:ターゲットが選択肢(Choice)フィールドのとき、ソースの値が既存の選択肢に無い場合の動作です。選べる値はcreate/reject/ignoreで、今回のPDIでは既定がcreateでした。createは新しい選択肢を作る、rejectはその行を弾く、ignoreはその列を無視する、という違いです。

    • use_source_script/source_script:列の値を単純コピーではなくスクリプトで計算して埋めます。今回のPDIではuse_source_script=trueのField Mapは4件でした。スクリプトの中身までは確認していません。

    • coalesce_case_sensitive:coalesceの一致判定で大文字小文字を区別するか(既定false)。

    これらは「列を1対1で写すだけでは足りないケース」に対応するための設定です。値の正規化、選択肢の扱い、計算列といった業務ルールが、実環境ではここに集約されることがあります。

    choice_actionの値は、次のURLでField Mapを開いて確認できます。

    https://<YourInstance>/sys_transform_entry_list.do


    画像

    実機で気づいたこと

    最初はImport SetもTransform Mapも、同じような「設定」を並べたテーブルだろうと考えていました。ところが実機を見ると、印象が変わります。Transform Map(14件)とField Map(119件)は、Application File(sys_metadata)を継承する構成データとして常に存在していました。一方でImport Setと取込行は、今回0件です。取込を1回実行するたびに動的に作られる、実行ログに近いテーブルだったわけです。常駐する「設計図」と、毎回作られる「実行の記録」という性質の違いに、件数を数えて初めて気づきました。

    coalesce=trueのField Mapは119件中14件で、Transform Mapの件数(14件)とちょうど同じでした。1マップにつき重複判定キーを複数本置く構成もありうるはずですが、今回のOOTBでは1マップにつきおおむね1列で足りていたことになります。マップごとの内訳までは数えていないので、この一致がルールなのか偶然なのかは分かりません。それでも「複数のcoalesceキーを持つマップは少数派らしい」という手触りは得られました。

    choice_actionの既定がcreateだった点も意外でした。選択肢に無い値が来たら弾かれる(reject)だろうと予想していたのですが、実際は何もカスタマイズしなければ、黙って新しい選択肢が追加される仕様です。取込を繰り返すたびに選択肢リストが静かに増えていく可能性があるため、Choiceフィールドをターゲットにするマップでは、この既定値を意識しておいたほうがよさそうです。

    実務では何に使えるか:調査の3ステップ

    取り込んだデータが増えない、逆に重複するという相談を受けたとき、自分は次の順番で確認します。

    1. Import Set一覧(sys_import_set_list.do)で対象の取込ジョブのstateを見る。loadedで止まっていればTransformがまだ走っていない状態、processedまで進んでいれば変換自体は完了しています。

    2. 対象のTransform Mapに紐づくField Map一覧を開き、coalesce=trueの列を確認する。ここが空、もしくはソース側の値が揺れていると、毎回insertされて重複します。

    3. ターゲットが選択肢フィールドの場合はchoice_actionを確認する。既定のcreateのままだと、想定外の値が来るたびに選択肢が増え続けます。

    この3点を上から順に見ていくだけで、取込自体が止まっているのか、重複判定の設定が原因なのか、選択肢が想定外に増えているのかを切り分けられます。原因を絞り込んでから該当のField Mapを開くほうが、いきなり取込データ全体を見直すより早く終わります。

    よくある質問

    Q1. Import Setが0件なのはおかしいですか

    おかしくありません。Import Setと取込行は、Load Dataを実行した瞬間に作られるランタイムデータです。今回のPDIのように取込を1度も実行していない環境では、0件のままで正常です。件数を見て「初期不良では」と焦る必要はありません。

    Q2. Transform MapとField Map、どちらから直せばいいですか

    直したい内容によります。ソース列とターゲット列の対応そのもの(どの列をどこに写すか、coalesceを付けるか)を変えたいならField Mapです。取込元・取込先のテーブルを丸ごと変えたい、複数マップの実行順を変えたいといった話ならTransform Map側になります。まずField Mapを疑い、テーブルの組み合わせに手を入れる必要が出たときだけTransform Mapを開く、という順番がおすすめです。

    Q3. coalesceは複数の列に付けてもいいですか

    公式ドキュメントによれば、複数の列にcoalesce=trueを付けると、その組み合わせ全体が一致したときに同一レコードとみなす仕組みです。今回のPDIのOOTBでは、1マップにつき1列というシンプルな構成が中心で、複数列を組み合わせた例までは見つかりませんでした。

    Q4. choice_actionでrejectを選ぶとどうなりますか

    rejectを選ぶと、選択肢に無い値が来た行そのものが取り込まれません。似た設定のignoreは、その列だけを無視して他の列は取り込む点が異なります。値の正しさを厳しく保ちたい列はreject、多少の欠落を許容してでも行自体は残したい列はignore、という使い分けになります。

    さらに詳しく知りたい人へ

    参考リンク

    実機で確かめた詳細

    ここからは実機確認用の記録です。読み物としては飛ばしても構いません。

    用語

    • PDI:Personal Developer Instance(無料の検証用インスタンス)

    • OOTB:Out of the Box(初期設定のまま)

    • Import Set(sys_import_set):外部データを受けるステージングの取込単位

    • 動的import テーブル:取込先ごとに作られる、生データの取込行を保持するテーブル

    • Transform Map(sys_transform_map):ソース→ターゲットの変換ルール(親)

    • Field Map(sys_transform_entry):列1組の対応(子・mapで親を参照)

    • coalesce:重複判定キー。一致すればupdate、不一致ならinsert

    実機で調べるときに開いたURL

    Import Set 定義      : sys_db_object_list.do?sysparm_query=name=sys_import_set
    Import Set 一覧      : sys_import_set_list.do
    Transform Map 一覧   : sys_transform_map_list.do
    Field Map 一覧       : sys_transform_entry_list.do
    coalesce の Field Map : sys_transform_entry_list.do?sysparm_query=coalesce=true
    state 選択肢         : sys_choice_list.do?sysparm_query=name=sys_import_set^element=state^inactive=false^ORDERBYsequence


    画像

    選択肢の値

    • sys_import_set.state(sequence順):loading=Loading/loaded=Loaded/processed=Processed/cancelled=Cancelled

    • sys_import_set.mode:asynchronous=Asynchronous(既定)/synchronous=Synchronous

    • sys_transform_entry.choice_action:create(既定)/reject/ignore

    レコード件数の内訳

    • sys_transform_map(変換マップ)… 14 / うちactive=true … 14

    • sys_transform_entry(Field Map)… 119 / うちcoalesce=true … 14 / use_source_script=true … 4

    • sys_import_set(取込単位)… 0 / sys_import_set_row(取込行)… 0(このPDIで取込未実行のため)

    • sys_data_source(データソース)… 17 / scheduled_import_set(定期取込)… 2

    • テーブル階層:sys_import_set/sys_import_set_rowはsuper_class空(ルート)。sys_transform_map(Table Transform Map)/sys_transform_entry(Field Map)はApplication File(sys_metadata)を継承

    • 固有フィールド数:sys_transform_map 12/sys_transform_entry 14/sys_import_set 20/sys_import_set_row 17

    検証環境と未検証範囲

    確認した範囲は次のとおりです。

    • sys_import_set/sys_import_set_row/sys_transform_map/sys_transform_entryの階層・固有フィールド数・主要フィールドと参照先

    • state/mode/choice_actionの選択肢

    • 各テーブルの件数、coalesce=true件数、OOTBの変換マップ14件

    • Userマップのフィールド構成(coalesce=email)

    すべてPDI(Zurich/OOTB)で取得し、2026-08-08に再確認しています。

    確認していない範囲は次のとおりです。

    • 動的importテーブルの内部スキーマ

    • 実際の取込実行時にinsert/updateがどう確定するか

    • run_script/source_scriptの中身、マップごとのcoalesce内訳

    • Data Source(CSV/Excel/JDBC)の接続設定、Scheduled Importの動作

    • Robust Transform Engine(RTE)の有無・挙動

    これらは別記事で扱います。

    今回はPDIのOOTB(初期設定)を前提に、テーブルの構造と件数を確認しました。実環境では、既存のカスタマイズや実際の取込データによって、件数・挙動が変わります。


    このシリーズの記事一覧

    ServiceNowの機能を1テーマずつ実機で確かめた記事を、分類ごとにまとめています。読みたいテーマから辿れます。

    → ServiceNow 観察日記 - 目次 -

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

    あなたへのおすすめ