========================= Direct I/O formatted text ========================= この文書では、レコードやフィールドを区切り文字によって分割する様々なデータ形式を Direct I/O で取り扱うための機能「Direct I/O formatted text」について説明します。 概要 ==== Direct I/O formatted text は、Direct I/Oで以下のようなデータ形式を持つテキストファイルを読み書きするための汎用的な機能を提供します。 * レコード間が改行文字で区切られている * フィールド間が任意の1文字(タブやカンマなど)で区切られている * フィールドの位置(並び順)がフィールドの種類に対応する 特徴 ---- Direct I/O formatted text は、以下のような特徴を持っています。 多様なデータ形式を扱うきめ細かな設定が可能 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ テキストファイルのエンコーディングやフィールド間の区切り文字をはじめ、 フィールド値の整形形式やエスケープの動作設定、 ``NULL`` や空文字に対する取り扱いなど、 様々なデータ形式に関する設定をレコード全体、及びフィールド単位にそれぞれ設定することができます。 従来、Direct I/Oでデータ取り込みを行うために事前にデータ整形処理が必要であったような場合においても、Direct I/O formatted textを利用することで直接そのようなデータを取り扱うことが可能になります。 不整合データに対する柔軟な動作設定が可能 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ データ形式の定義と実際のデータの内容に不整合があった場合に、 エラーとして異常終了とする、警告を出力して処理を継続する、または単にスキップするなど様々な動作がレコード全体、及びフィールド単位にそれぞれ設定可能です。 エラーや警告時にはエラー箇所と不整合の内容を示す詳細な情報が出力されます。 これらの機能によって想定外のデータに対して迅速に対応できるほか、外部システムやアプリケーションの仕様変更などに伴いアプリケーションとデータに不整合が発生するような場合でも、柔軟な運用、移行を可能にすることを支援します。 データフォーマットの作成 ======================== Direct I/O formatted text を利用したデータフォーマットを定義するには、対象のデータモデルに対応するDMDLスクリプトにDirect I/O formatted text用のデータモデル属性を指定します。 本バージョン時点で、Direct I/O formatted textは以下の2種類のデータモデル属性が利用できます。 * ``@directio.text.tabular`` * ``@directio.text.csv`` この2種類のデータモデル属性で取り扱うデータフォーマットはいずれも `概要`_ で示したようなテキストファイルを扱うものです。 その動作や設定可能な項目などは多くの部分で共通していますが、異なる部分は主にフィールド中のメタ文字に対する扱いと、デフォルトの設定です。 ここでのメタ文字とは、フィールド区切り文字などのファイルフォーマット自体に関わる文字のことです。 以下、それぞれのデータモデル属性が扱うデータフォーマットの概要と使い方を説明します。 ``@directio.text.tabular`` -------------------------- ``@directio.text.tabular`` はフィールド中のメタ文字を「エスケープシーケンス」によって扱います。 エスケープシーケンスは「エスケープ文字+後続文字」という形式でフィールドデータとして表現します。エスケープ文字として使用する文字や、エスケープ時の動作などは ``@directio.text.tabular`` 属性の設定により細かく指定することが可能です。 デフォルトの設定はエスケープシーケンスは無効、フィールド間の区切り文字はHT(水平タブ)、といった設定を持ちます。 この形式に対応した ``DataFormat`` の実装クラスを自動的に生成するには、対象のデータモデルに対応するDMDLスクリプトに ``@directio.text.tabular`` を指定します。 .. code-block:: dmdl @directio.text.tabular document = { "the name of this document" name : TEXT; "the content of this document" content : TEXT; }; 上記のように記述してデータモデルクラスを生成すると、 ``<出力先パッケージ>.text.<データモデル名>TabularTextFormat`` というクラスが自動生成されます。 このクラスは ``DataFormat`` を実装し、データモデル内のプロパティが区切り文字によって分離されて順番に並んでいるようなテキストファイルを取り扱えます。 また、 単純な :ref:`directio-dsl-input-description` と :ref:`directio-dsl-output-description` の骨格も自動生成します。 前者は ``<出力先パッケージ>.text.Abstract<データモデル名>TabularTextInputDescription`` 、後者は ``<出力先パッケージ>.text.Abstract<データモデル名>TabularTextOutputDescription`` というクラス名で生成します。必要に応じて継承して利用してください。 ``@directio.text.csv`` ---------------------- ``@directio.text.csv`` は :rfc:`4180` で提唱されているCSVの形式に基いて、フィールド中のメタ文字を「クウォート」によって扱います。クウォート処理の基本的な動作は、フィールドにメタ文字が含まれる場合にフィールド全体をクウォート文字で囲うことで取り扱うものです。クウォート文字として使用する文字や、クウォート方式などは ``@directio.text.csv`` 属性の設定により細かく指定することが可能です。 デフォルトの設定はクウォート文字に ``"`` (ダブルクウォート)、フィールド間の区切り文字は ``,`` (カンマ)、といった設定を持ちます。 この形式に対応した ``DataFormat`` の実装クラスを自動的に生成するには、対象のデータモデルに対応するDMDLスクリプトに ``@directio.text.csv`` を指定します。 .. code-block:: dmdl @directio.text.csv document = { "the name of this document" name : TEXT; "the content of this document" content : TEXT; }; 上記のように記述してデータモデルクラスを生成すると、 ``<出力先パッケージ>.text.<データモデル名>CsvTextFormat`` というクラスが自動生成されます。 このクラスは ``DataFormat`` を実装し、データモデル内のプロパティが区切り文字によって分離されて順番に並んでいるようなテキストファイルを取り扱えます。 また、 単純な :ref:`directio-dsl-input-description` と :ref:`directio-dsl-output-description` の骨格も自動生成します。 前者は ``<出力先パッケージ>.text.Abstract<データモデル名>CsvTextInputDescription`` 、後者は ``<出力先パッケージ>.text.Abstract<データモデル名>CsvTextOutputDescription`` というクラス名で生成します。必要に応じて継承して利用してください。 .. _directio-formatted-text-comparison: 他のデータフォーマット機能との関係 ================================== Direct I/O でテキストファイルを扱うには、本書で説明する Direct I/O formatted text の他にも以下のような機能を利用できます。 * :doc:`csv-format` * :doc:`directio-tsv` (非推奨機能) * :doc:`directio-line` これらの機能と Direct I/O formatted text では提供する機能の一部が重複、または類似しているため、以下ではそれぞれの機能のおおまかな差異や使い分けの指針を説明していきます。 .. attention:: ここで説明する内容は現時点のもので、将来のバージョンで変更される可能性があります。 Direct I/O CSV -------------- :doc:`csv-format` と Direct I/O formatted text ( ``@directio.text.csv`` ) は両者とも :rfc:`4180` で提唱されているCSVの形式に基づいたデータフォーマットを扱う機能です。 機能面では、 Direct I/O formatted text は Direct I/O CSV よりも細かいデータフォーマットの指定が可能で、不整合データの取り扱いも柔軟に設定することができます。 Direct I/O CSV を利用する場合には事前にフォーマット整形が必要となるようなケースでは、Direct I/O formatted text によってより効率のよい対応が可能となる場合があります。 性能面では、現時点において Direct I/O CSV は Direct I/O formatted text よりも高速に動作します。 パフォーマンス差異の度合いは実行環境や扱うファイルの特性にも変わりますが、手元の検証ではおおよそ20%から30%程度、 Direct I/O CSV のほうが高速に動作するようです。 これらの機能の特性を考慮し、また実際に取り扱うデータフォーマットや実行環境の特性に応じて機能を選択するとよいでしょう。 Direct I/O TSV -------------- :doc:`directio-tsv` は TSV形式のデータフォーマットを使う機能ですが、 TSV形式のデータフォーマットについては Direct I/O formatted text を利用することを推奨します。 Direct I/O TSV は本バージョンでは非推奨機能です。その主な理由は本機能で対応可能なデータフォーマットが制限的で、汎用性に乏しいことによります。また不整合データの取り扱いについても他のデータフォーマット機能と比べて劣る部分があります。 なお、現時点で今後 Direct I/O TSV に関して大幅な拡張や変更を行う予定はありません。 Direct I/O line --------------- :doc:`directio-line` はファイル内の行文字列とデータモデル内の1つの文字列型プロパティをマッピングするシンプルな機能を提供します。 Direct I/O lineが想定する用途は主に2つあり、1つは `JSON `_ や `LTSV `_ といった、レコードが1行で表現されるがデータの構成に区切り文字やフィールドの位置以外を利用するテキストデータフォーマットを取り扱う場合です。このような用途では引き続き Direct I/O line の利用を推奨します。 もう1つは、CSVやTSV形式の入力ファイルを扱いたいが、Direct I/O CSV や Direct I/O TSV が提供する機能では直接扱うことができず、テキスト内容の整形や形式変換、バリデーションチェックなどの事前処理が必要となる場合です。 このようなケースのいくつかは Direct I/O formatted text が提供する機能によって、直接データを扱うことが可能となる場合があります。 データフォーマットの設定 ======================== ``@directio.text.tabular`` および ``@directio.text.csv`` 属性の要素には、データフォーマットに関する次のような設定を指定することができます。 * `テキスト全体の構成`_ * `ファイルヘッダの構成`_ * `データ型の形式`_ * `入力時の動作`_ * `出力時の動作`_ * `エスケープ方式`_ ( ``@directio.text.tabular`` のみ ) * `クウォート方式`_ ( ``@directio.text.csv`` のみ ) ここで指定する設定項目のうち、データフィールドに対して適用される設定については、全てのデータフィールドに共通の設定値として適用されます。 データフィールド単位で個別に設定を指定したい場合は、 後述の `データフィールドの設定`_ を行うことでデータフィールド単位に設定を上書きすることができます。 以下はDMDLスクリプトの記述例です。 .. code-block:: dmdl @directio.text.tabular( charset = "ISO-2022-JP", header = force, compression = "gzip", true_format = "1", false_format = "0", date_format = "yyyy/MM/dd", datetime_format = "yyyy/MM/dd HH:mm:ss", ) model = { ... }; テキスト全体の構成 ------------------ ``charset`` ファイルの文字セットエンコーディングを表す文字列。 指定した文字セットエンコーディングが ASCII または ASCIIの上位互換 のいずれでもない場合、 :ref:`directio-input-split` が行われなくなる。 既定値: ``"UTF-8"`` ``compression`` ファイルの圧縮形式。 ``"gzip"`` または ``CompressionCodec`` [#]_ のサブタイプのクラス名を指定する。 ここで指定した圧縮形式で対象のファイルが読み書きされるようになるが、代わりに :ref:`directio-input-split` が行われなくなる。 既定値: 未指定 (圧縮無し) ``line_separator`` ファイル出力時に使用する、レコード間を区切るテキストの改行文字。以下のオプションから指定する。 * ``unix`` : LF のみ * ``windows`` : CRLF の組み合わせ 入力時にはこの設定を利用せず、 LF, CR, CRLF のいずれも改行として扱う。 ただし CR のみの場合には :ref:`directio-input-split` が行われなくなる。 入力の末尾に改行文字が出現した場合、EOFとして扱う(次行を空レコードとして取り扱わない)。 既定値: * ``@directio.text.tabular`` : ``unix`` * ``@directio.text.csv`` : ``windows`` ``field_separator`` フィールド間の区切り文字。任意の1文字を指定する。 ``"\r"`` (CR), ``"\n"`` (LF), 及び ``escape_character`` で指定した値は指定できない。 既定値: * ``@directio.text.tabular`` : ``"\t"`` (HT:水平タブ) * ``@directio.text.csv`` : ``","`` (カンマ) .. [#] ``org.apache.hadoop.io.compress.CompressionCodec`` ファイルヘッダの構成 -------------------- ``header`` ファイルヘッダの処理方法。以下のオプションから指定する。 * ``nothing`` : 何もしない * ``force`` : 入力時に先頭行をスキップし、出力時に先頭行にヘッダを出力する * ``skip`` : 入力時に先頭行がヘッダにマッチすればスキップし、出力時はヘッダを出力しない * ``auto`` : 入力時に先頭行がヘッダにマッチすればスキップし、出力時に先頭行にヘッダを出力する 既定値: ``nothing`` データ型の形式 -------------- ``true_format`` データモデルの論理値型 ( ``BOOLEAN`` ) で ``TRUE`` を表す文字列。 ``false_format`` , ``null_format`` と同じ文字列は使用できない。 ``trim_input`` を利用した場合、 ``true_format`` の前後に空白文字が含まれているとマッチしない。 既定値: ``"true"`` ``false_format`` データモデルの論理値型 ( ``BOOLEAN`` ) で ``FALSE`` を表す文字列。 ``true_format`` , ``null_format`` と同じ文字列は使用できない。 ``trim_input`` を利用した場合、 ``false_format`` の前後に空白文字が含まれているとマッチしない。 既定値: ``"false"`` ``number_format`` データモデルの数値型 ( ``INT`` , ``LONG`` , ``FLOAT`` , ``DOUBLE`` , ``DECIMAL`` , ``BYTE`` , ``SHORT`` ) の形式。 ``DecimalFormat`` [#]_ の形式で指定する。 ``null`` を指定した場合は未指定として扱う。 未指定の場合はDirect I/O formatted textが規定する標準の方式で解析、及び出力を行う。 既定値: 未指定 ``decimal_output_style`` データモデルの10進数型 ( ``DECIMAL`` ) の出力形式。以下のオプションから指定する。 * ``plain`` : 指数表現なし * ``scientific`` : 必要ならば、指数表現を ``10^n`` の単位で行う * ``engineering`` : 必要ならば、指数表現を ``10^(n*3)`` の単位で行う 入力時にはこの設定を利用せず、全ての形式に対応する。 該当フィールドに ``number_format`` が指定されている場合、 ``decimal_output_style`` で指定した内容は無視される。 既定値: ``scientific`` ``date_format`` データモデルの日付型 ( ``DATE`` ) の形式。 ``SimpleDateFormat`` [#]_ の形式で指定する。 既定値: ``"yyyy-MM-dd"`` ``datetime_format`` データモデルの日時型 ( ``DATETIME`` ) の形式。 ``SimpleDateFormat`` の形式で指定する。 既定値: ``"yyyy-MM-dd HH:mm:ss"`` ``null_format`` ``NULL`` 値を表す形式。任意の文字列を指定する。 ``null`` を指定した場合は未指定として扱う。 ``NULL`` 値が未指定の場合、以下のような動作となる。 * 入力データには ``NULL`` を表す値を含められない。 * 出力データに ``NULL`` が含まれる場合には ``on_unmappable_output`` の設定に従ってエラー処理を行い、その結果ファイルの出力が実行される場合には、空文字列が出力される。 ``@directio.text.tabular`` を利用する場合には、 ``null`` 値の指定は ``escape_sequence`` の設定も利用される。その場合の動作を以下に示す。 * ``null_format`` が未指定である場合、 ``escape_sequence`` で定義した ``null`` 値の設定を利用する。 * ``escape_sequence`` でも ``null`` 値が未指定の場合、上記に示す「 ``NULL`` 値が未指定の場合」と同じ動作となる。 * ``null_format`` と ``escape_sequence`` に両方 ``null`` 値が設定されている場合、 ``null_format`` の設定が優先して利用される。 既定値: 未指定 .. [#] ``java.text.DecimalFormat`` .. [#] ``java.text.SimpleDateFormat`` 入力時の動作 ------------ ``trim_input`` 入力時に、フィールドの先頭末尾の空白文字を除去するかどうか。以下のオプションから指定する。 * ``true`` : 除去する * ``false`` : 除去しない この操作によってフィールドが空になった場合、 ``skip_empty_input`` の対象となる。 既定値: ``false`` ``skip_empty_input`` 入力時に、フィールドの文字列が空である場合の動作。以下のオプションから指定する。 * ``true`` : 読み飛ばす * ``false`` : 空文字列として扱う 既定値: ``false`` ``on_malformed_input`` 入力時に、不正なフィールド文字列が検出された場合の動作。以下のオプションから指定する。 * ``error`` : エラーログを出力して、異常終了する。 * ``report`` : 警告ログを出力して、プロパティに ``NULL`` を設定する。 * ``ignore`` : プロパティに ``NULL`` を設定する。 既定値: ``error`` ``on_more_input`` 入力時に、レコードに余剰フィールドが検出された場合の動作。以下のオプションから指定する。 * ``error`` : エラーログを出力して、異常終了する。 * ``report`` : 警告ログを出力して、余剰フィールドを無視する。 * ``ignore`` : 余剰フィールドを無視する。 既定値: ``error`` ``on_less_input`` 入力時に、レコードにフィールドが不足している場合の動作。以下のオプションから指定する。 * ``error`` : エラーログを出力して、異常終了する。 * ``report`` : 警告ログを出力して、プロパティに ``NULL`` を設定する。 * ``ignore`` : プロパティに ``NULL`` を設定する。 既定値: ``error`` 出力時の動作 ------------ ``on_unmappable_output`` 出力時に、不正な文字が含まれている場合の動作。以下のオプションから指定する。 * ``error`` : エラーログを出力して、異常終了する。 * ``report`` : 警告ログを出力して、そのまま出力。 * ``ignore`` : そのまま出力。 データ内にエスケープやクウォートで対処できないメタ文字や、マッピングが未指定で ``NULL`` が存在した場合などに該当する。 既定値: ``error`` エスケープ方式 -------------- エスケープ方式の設定は、 ``@directio.text.tabular`` 属性に対してのみ有効。 ``escape_character`` エスケープシーケンス(エスケープ文字+後続文字)で使用するエスケープ文字。任意の1文字を指定する。 ``"\r"`` , ``"\n"`` , 及び ``field_separator`` で指定した値は指定できない。 既定値: 未指定 (エスケープシーケンスを利用できない) ``escape_line_separator`` 改行文字をエスケープ可能にするかどうか。以下のオプションから指定する。 * ``true`` - 改行文字をエスケープ可能にする。このオプションを指定した場合、 :ref:`directio-input-split` が行われなくなる。 * ``false`` - 改行文字をエスケープ不可能にする。 この設定を利用するには ``escape_character`` も定義する必要がある。 既定値: ``false`` ``escape_sequence`` 利用可能なエスケープの一覧。マップ形式 ( ``{ "キー":"値", "キー":"値", ... }`` ) で指定する。 キー キーにはエスケープシーケンスの後続文字(エスケープ文字を除いた1文字)を指定する。 キーには ``"\r"`` , ``"\n"`` といった、改行文字の構成要素を含められない。 改行文字のエスケープするための設定は ``escape_line_separator`` で指定する。 値 値にはシーケンスに対応する1文字を指定する。 値にはNULLを表す特別なシンボル ``null`` を利用出来る。 フィールド全体がそのシーケンスのみの値である場合、そのフィールド値はNULLとしてエスケープされる。 サロゲートペアはキー・値のいずれにも利用できない。 この設定を利用するには ``escape_character`` も定義する必要がある。 既定値: なし クウォート方式 -------------- クウォート方式の設定は、 ``@directio.text.csv`` 属性に対してのみ有効。 ``quote_character`` フィールドのクウォートで使用するクウォート文字。 ``"\r"`` , ``"\n"`` , 及び ``field_separator`` で指定した値は指定できない。 既定値: ``"\""`` (ダブルクウォート) ``allow_linefeed`` フィールドにLF(改行文字)を含められるかどうか。以下のオプションから指定する。 * ``true`` : 含められる。このオプションを指定した場合、 :ref:`directio-input-split` が行われなくなる。 * ``false`` : 含められない。フィールドにLFが含まれる場合はエラーとして扱う。 既定値: ``false`` ``quote_style`` 出力時のクォート方式。以下のオプションから指定する。 * ``always`` : 常にクウォートを行う。 * ``never`` : 常にクウォートを行わない。フィールドに CR, LF, ``field_separator``, ``quote_character`` のいずれかが含まれる場合はエラーとして扱う。 * ``needed`` : フィールドに CR, LF, ``field_separator``, ``quote_character`` のいずれかが出現した場合のみクウォートを行う。 入力時にはこの設定を利用せず、全てのクウォート方式に対応する。 既定値: ``needed`` ``header_quote_style`` 出力時ヘッダのクォート方式。以下のオプションから指定する。 * ``always`` : 常にクウォートを行う。 * ``never`` : 常にクウォートを行わない。フィールドに CR, LF, ``field_separator``, ``quote_character`` のいずれかが含まれる場合はエラーとして扱う。 * ``needed`` : フィールドに CR, LF, ``field_separator``, ``quote_character`` のいずれかが出現した場合のみクウォートを行う。 入力時にはこの設定を利用せず、全てのクウォート方式に対応する。 未指定の場合、 ``quote_style`` と同じクウォート方式を利用する。 既定値: 未指定 データフィールドの設定 ====================== Direct I/O formatted text が扱うテキストファイルのデータフィールドに関する設定は、DMDLスクリプトのデータモデルに含まれるそれぞれのプロパティに ``@directio.text.field`` 属性を指定します。 ``@directio.text.field`` 属性の要素には、次のような設定を指定することができます。 * `フィールドの基本情報`_ * `フィールドのデータフォーマット`_ その他、データフィールドに対する個別の属性を利用した、次のような設定を指定することができます。 * `フィールドの除外`_ * `ファイル情報の取得`_ 以下はDMDLスクリプトの記述例です。 .. code-block:: dmdl @directio.text.tabular ( ... ) model = { @directio.text.field ( name = "数量", null_format = "", on_unmappable_output = report, ) amount : INT; }; フィールドの基本情報 -------------------- ``name`` フィールド名を表す文字列。 ``header`` の設定によりファイルヘッダを出力する場合、ここで指定したフィールド名がヘッダに利用される。未指定の場合、プロパティ名がヘッダに利用される。 既定値: 未指定 フィールドのデータフォーマット ------------------------------ `データフォーマットの設定`_ が持つ設定のうち、次の項目については ``@directio.text.field`` 属性に同名の要素を指定することでデータフィールド単位に設定を上書きすることができます。 * `データ型の形式`_ * ``true_format`` * ``false_format`` * ``number_format`` * ``decimal_output_style`` * ``date_format`` * ``datetime_format`` * ``null_format`` * `入力時の動作`_ * ``trim_input`` * ``skip_empty_input`` * ``on_malformed_input`` * `出力時の動作`_ * ``on_unmappable_output`` * `クウォート方式`_ * ``quote_style`` ( ``@directio.text.csv`` 内のプロパティのみ ) フィールドの除外 ---------------- データモデルに定義されている特定のプロパティをデータフィールドとして取り扱いたくない場合の設定です。 ``@directio.text.ignore`` このプロパティをデータフィールドとして取り扱わない。 ファイル情報の取得 ------------------ 入力時のテキストファイルに関する情報を取得する場合、それぞれ次の属性をプロパティに指定します。 これらの属性はファイル入力時のみ有効です。 これらの属性を指定したプロパティは、ファイル出力時にはデータフィールドから除外されます。 ``@directio.text.file_name`` このフィールドに、該当データレコードが含まれるファイルパスを設定する。 この属性を指定するプロパティには ``TEXT`` 型を指定する必要がある。 ``@directio.text.line_number`` このフィールドに、該当データレコードの開始行番号(テキスト行番号)を設定する。 この属性を指定するプロパティには ``INT`` または ``LONG`` 型を指定する必要がある。 この属性が指定された場合、 :ref:`directio-input-split` が行われなくなる。 ``@directio.text.record_number`` このフィールドに、該当データレコードのレコード番号を設定する。 この属性を指定するプロパティには ``INT`` または ``LONG`` 型を指定する必要がある。 この属性が指定された場合、 :ref:`directio-input-split` が行われなくなる。 設定例 ====== エスケープシーケンス -------------------- ``@directio.text.tabular`` でエスケープシーケンスを利用するための設定例です。 ここでは以下のようなエスケープシーケンスを定義します。 * ``\`` をエスケープ文字に指定 * 改行文字 ``\r`` , ``\n`` , タブ ``\t`` をエスケープ * エスケープ文字自体をエスケープ * ``\N`` をNULLとして扱う .. code-block:: dmdl @directio.text.tabular ( escape_character = "\\", escape_sequence = { "r" : "\r", "n" : "\n", "t" : "\t", "\\" : "\\", "N" : null, }, ) ... .. note:: DMDLスクリプト内ではJavaの文字列リテラルと同様に ``\`` はエスケープシーケンスとして扱われるため、各要素の値に ``\`` を指定したい場合は ``"\\"`` のようにバックスラッシュを2つ記述します。 空文字列とNULLの扱い -------------------- Direct I/O formatted textでは、空文字列とNULLに関して標準では以下のように設定されています。 * ``skip_empty_input = false`` (フィールド値が空値の場合は空文字列として扱う) * ``null_format = (未指定)`` これらの設定により、標準の動作は以下のような強い制約を伴います。 * 入力ファイル内のフィールド値が空文字列となっている場合、そのフィールドが ``TEXT`` 型以外のプロパティと対応付けられていると不正な値として扱われる。 * 出力時にデータモデル内のプロパティ値に ``null`` が含まれると不正な値として扱われる。 データモデル全体で空文字列を ``NULL`` として扱う場合は、以下のように ``null_format`` を設定します。 .. code-block:: dmdl @directio.text.csv ( null_format = "", ) ... .. note:: 上記のデータモデル全体で空文字列を ``NULL`` として扱う動作は :doc:`csv-format` と同じ動作となります。 Direct I/O CSV から Direct I/O formatted text ( ``@directio.text.csv`` ) に移行するなどで、 Direct I/O CSV と同様の動作に設定したい場合には上例のように設定してください。 数値型のプロパティのみに対して空文字列を ``NULL`` として扱うなど、フィールド単位で ``null_format`` を設定することもできます。 .. code-block:: dmdl @directio.text.csv ( ... ) model = { @directio.text.field ( null_format = "", ) amount : INT; }; ``null_format`` による設定のほかに、不正な値を検出した場合の動作を変更し処理を続行させる方法もあります。 以下の設定は、数値型のフィールドに空文字列などの不正なフォーマットを検出した場合に警告を出力し、空文字列と ``null`` を相互にマッピングします。 .. code-block:: dmdl @directio.text.csv ( ... ) model = { @directio.text.field ( on_malformed_input = report, on_unmappable_output = report, ) amount : INT; }; .. attention:: ``null_format`` が未指定の場合、テストドライバのジョブフローやバッチのテスト実行時にテストドライバが ``NULL`` を取り扱う動作にも注意が必要です。 例えば :doc:`../testing/using-excel` などの方法で入力データを定義する際には、テストケースで利用しないプロパティを未定義にすることができますが、その際テストドライバは未定義のプロパティをNULLとして取り扱います。また同様に空のセルもNULLとして扱います。 テストドライバの ``NULL`` 値の扱いについては、 :doc:`../testing/using-excel` などのテストドライバのドキュメントを確認してください。