サポート > インポートとエクスポート機能活用ガイド > モデル定義変更時の対応
Wagby ではデータの移行前と移行後でモデル項目定義が変更された場合に、これを吸収できる仕組みを提供しています。ここではその方法を説明します。
変更ルールを吸収する仕組み
Wagbyによるインポート処理では、1件の処理毎に、XSLTと呼ばれる変換処理を通ります。 この変換ファイルは directory 要素の importxslfilename 属性 で指定されています。標準では次の処理に対応しています。
- 必須項目に値がセットされていない場合に、代わりの値を設定する。
ただし、次のような変更については手動で対応する必要があります。
- 項目の型が変更された場合
- 項目名(英語)が変更された場合
- 主キーや一意項目を追加した場合
通常、このような変更が発生したデータの移行には骨が折れます。しかし Wagby ではインポートに対する個別のルールを XSLT という形で指定できるため、多くの処理を(ルールを追加記述することによって)自動化することができます。すべてのデータを変更しようとする前に、XSLTによるルール記述ができないかどうかを検討してください。
XSLTの書式についての説明は本ガイドの範囲を超えるので割愛します。ここでは、具体的な例を用いて説明します。
項目の型が変更された場合
項目の型を「文字列」から「数値」に変更した場合などです。 このとき、項目の値に数値でない文字列があると読み込みエラーとなりますので、このようなデータを無視する、または変換するための処理をXSLT内に記述します。
例:項目 age を文字列から数値型に変更したため、数値以外のデータを無視するようにするように設定する。
オリジナルの内容
<xsl:template match="age">
<age>
<xsl:value-of select="."/>
</age>
</xsl:template>
修正後の内容
<xsl:template match="age">
<age>
<xsl:if test="number(.) >= 0">
<xsl:value-of select="."/>
</xsl:if>
</age>
</xsl:template>
例:項目 job を文字列からマスタ参照に変更したため、元の文字列をコード値に変換する。
オリジナルの内容
<xsl:template match="job">
<job>
<xsl:value-of select="."/>
</job>
</xsl:template>
修正後の内容
<xsl:template match="job">
<job>
<xsl:choose>
<xsl:when test="text() = '学生'">
<xsl:text>1</xsl:text>
</xsl:when>
<xsl:when test="text() = '会社員'">
<xsl:text>2</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text>-1</xsl:text>
</xsl:otherwise>
</xsl:choose>
</job>
</xsl:template>
例:項目 publishdate の表記内容について「yyyy/MM/dd」を「yyyy-MM-dd」に変換したい。
オリジナルの内容
<xsl:template match="publishdate">
<publishdate>
<xsl:value-of select="."/>
</publishdate>
</xsl:template>
修正後の内容
<xsl:template match="publishdate">
<publishdate>
<xsl:choose>
<xsl:when test='contains(text(),"/")'>
<xsl:value-of
select='substring-before(text(),"/")'/>
-<xsl:value-of
select='substring-before(substring-after(
text(),"/"),"/")'/>
-<xsl:value-of select='substring-after(
substring-after(text(),"/"),"/")'/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select='text()'/>
</xsl:otherwise>
</xsl:choose>
</publishdate>
</xsl:element>
項目名(英語)が変更された場合
項目名(英語)が「name」から「customername」に変更された場合など。自動生成された変換用 XSL では、このような意味的な変換は解釈できないため、手動で(変換用 XSL ファイルを)修正し、正しい項目にマッピングします。
例:項目名を「name」から「customername」に変更する。
オリジナルの内容
<xsl:template match="name">
<name>
<xsl:value-of select="."/>
</name>
</xsl:template>
修正後の内容
<xsl:template match="name">
<customername>
<xsl:value-of select="."/>
</customername>
</xsl:template>
主キーや一意項目を追加した場合
追加した主キーや一意項目の値が重複しないように配慮する必要があります。 ただしこのケースでは XSL による変換ではなく、対象データを直接、変更する方がよいかも知れません。
項目1,項目2,...を繰り返し項目に統合する
最初の設計を「担当者1」「担当者2」と定義していたが、これを「担当者」(繰り返し項目)に統合する場合です。
元のモデルでエクスポートしたときの XML ファイルが次のようになっていたとします。
<customer> <id>1000</id> <name1>山田</name1> <name2>佐藤</name2> </customer>
これを、次のような XML に変換した上で、新モデル側にインポートさせようというものです。
<customer> <id>1000</id> <name>山田</name> <name>佐藤</name> </customer>
変更した XSLT ファイルは次のようになります。
...(中略)...
<xsl:template match="/*">
<customer>
<xsl:choose>
<xsl:when test="id">
<xsl:apply-templates select="id[1]"/>
</xsl:when>
<xsl:otherwise>
<id>-1</id>
</xsl:otherwise>
</xsl:choose>
<xsl:apply-templates select="name"/>
<xsl:apply-templates select="name1"/><!-- 追加 -->
<xsl:apply-templates select="name2"/><!-- 追加 -->
</customer>
</xsl:template>
<xsl:template match="id">
<id>
<xsl:value-of select="."/>
</id>
</xsl:template>
<xsl:template match="name">
<name>
<xsl:value-of select="."/>
</name>
</xsl:template>
<xsl:template match="name1"><!-- 追加 -->
<name>
<xsl:value-of select="."/>
</name>
</xsl:template>
<xsl:template match="name2"><!-- 追加 -->
<name>
<xsl:value-of select="."/>
</name>
</xsl:template>
項目1,項目2,...を繰り返しコンテナに統合する
最初の設計を「担当者1」「担当者2」と定義していたが、これを「担当者」(繰り返しコンテナ内の項目)に統合する場合です。
元のモデルの定義は次のようになっています。
| 項目名(日本語) | 項目名(英語) | 項目の型 | 主キー | 繰り返し |
|---|---|---|---|---|
| ID | address_id | 整数 | ○ | |
| 担当者1 | con_member_id | 文字列 | ||
| 担当者2 | con_member_id2 | 文字列 |
また、このモデル定義でエクスポートしたときの XML ファイルが次のようになっていたとします。
<address> <address_id>1000</address_id> <con_member_id>田中</con_member_id> <con_member_id2>鈴木</con_member_id2> </address>
これを次のようなモデル定義に変換します。
| 項目名(日本語) | 項目名(英語) | 項目の型 | 主キー | 繰り返し |
|---|---|---|---|---|
| ID | address_id | 整数 | ○ | |
| レポート | report | (繰り返し項目のコンテナ) | ○ | |
| レポートID | report/id1 | (繰り返し項目コンテナ用のID) | ||
| 担当者 | report/syain | 文字列 | ||
| メモ | report/memo | 文字列 | ||
| メモ | report/date1 | 日付 |
具体的には、次に示す XML に変換した上で、新モデル側にインポートさせます。
<address> <address_id>1000</address_id> <report> <reportjshid>0</reportjshid> <id1>1</id1> <syain>田中</syain> </report> <report> <reportjshid>1</reportjshid> <id1>2</id1> <syain>鈴木</syain> </report> </address>
「reportjshid」という項目は、Wagby が内部で利用します。Wagby 定義ファイルには用意されていませんが、インポート時には必要となります。
変更した XSLT ファイルは次のようになります。
...(中略)...
<xsl:template match="/*">
<address>
<xsl:choose>
<xsl:when test="address_id">
<xsl:apply-templates select="address_id[1]"/>
</xsl:when>
<xsl:otherwise>
<address_id>-1</address_id>
</xsl:otherwise>
</xsl:choose>
<xsl:apply-templates
select="report | con_member_id | con_member_id2"/>
</address>
</xsl:template>
<xsl:template match="address_id">
<address_id>
<xsl:value-of select="."/>
</address_id>
</xsl:template>
<xsl:template match="report">
<report>
<xsl:choose>
<xsl:when test="/*/address_id">
<xsl:apply-templates select="/*/address_id[1]"/>
</xsl:when>
<xsl:otherwise>
<address_id>-1</address_id>
</xsl:otherwise>
</xsl:choose>
<reportjshid>
<xsl:value-of select="position()-1"/>
</reportjshid>
<xsl:apply-templates select="id[1]"/>
<xsl:apply-templates select="syain[1]"/>
<xsl:apply-templates select="memo[1]"/>
<xsl:apply-templates select="date1[1]"/>
</report>
</xsl:template>
<xsl:template match="report/id">
<id>
<xsl:value-of select="."/>
</id>
</xsl:template>
<xsl:template match="report/syain">
<syain>
<xsl:value-of select="."/>
</syain>
</xsl:template>
<xsl:template match="report/memo">
<memo>
<xsl:value-of select="."/>
</memo>
</xsl:template>
<xsl:template match="report/date1">
<date1>
<xsl:value-of select="."/>
</date1>
</xsl:template>
<xsl:template match="con_member_id | con_member_id2">
<report>
<xsl:choose>
<xsl:when test="/*/address_id">
<xsl:apply-templates select="/*/address_id[1]"/>
</xsl:when>
<xsl:otherwise>
<address_id>-1</address_id>
</xsl:otherwise>
</xsl:choose>
<reportjshid>
<xsl:value-of select="position()-1"/>
</reportjshid>
<id1>
<xsl:value-of select="position()"/>
</id1>
<syain>
<xsl:value-of select="text()"/>
</syain>
</report>
</xsl:template>
