🗒️

移行業務の改善 その3 CSV加工の分離

2023/09/05に公開

はじめに

弊社では ecforce というシステムをSaaSという形でサービスを提供しています。
ecforceの導入を希望されるクライアント様には、大きく2パターンがあります。

  • 新規で ECを立ち上げたいというクライアント様
  • 別のカートシステムを現在使っており、ecforceに乗り換えたいというクライアント様

後者につきまして、当然ながら顧客や注文データをリセットするわけにもいかないので、 既存データも引き継ぎたい という要望をいただくことが大多数です。
ただ他社のカートシステムとecforceではデータ構造が異なるので、データを抽出してそのままecforceのデータベースにインポートできるわけではありません。

この後者の要望を叶えるためにはデータを

  1. 抽出し
  2. 加工した上で
  3. ecforceのデータベースにインポートする

という手順を踏む必要があります。
これを社内では 移行業務 と呼んでおり、弊社にはこの移行業務を行う専門チームがあります。

本題

SQLの高速化と並列処理の導入によって、スクリプト自体は速くなりました。
ただ、移行業務のさらなる高速化を検討していたことに加え、案件によってスクリプトを実装しなければならない点についても課題感を持っていました。

ecforceのバックエンドはRailsに依存していたため、データのインポートも同様、Railsのモデルクラスへの依存を切り離せないと判断しました。
ただし データの加工については、インポート処理と分離できるのではないか という仮説を立てました。
データの加工を分離させるにあたり、以下4つを重要視しました。

  • Rubyスクリプトよりも高速であること
  • コストが安いこと
  • 案件によるイレギュラーな加工でも自分たちでコントロールできること
  • ノーコードツールを実現することで単純な処理にエンジニア工数を使わないようにすること

サービスやツールを探したところ、AWSの GlueDataBrew を見つけました。
コストとイレギュラー対応がネックになり、導入には至らなかったものの、DataBrewの レシピ という概念に触れました。
これは データの加工をするための簡単な関数を組み合わせで使えば、やりたいことはだいたい満たせる といったものです。
このDataBrewの レシピ という考え方に基づいて、移行業務におけるデータ加工を、PythonのCSVライブラリ Pandas で独自で実装することにしました。

実例

文章だけだと伝わりづらいので、実例を用いて説明します。

移行元CSV

商品名 商品カテゴリ名 商品コード 定期商品かどうか 販売価格
Tシャツ アパレル A3831448FD いいえ 2000
プロテイン 健康食品 D1530E86DF はい 1500
パーカー アパレル DDD71B95A4 いいえ 3000

加工したCSV

name product_category_id number is_recurring sales_price
Tシャツ 1 A3831448FD false 2000
プロテイン 2 D1530E86DF true 1500
パーカー 1 DDD71B95A4 false 3000

例えば上記 移行元CSV加工したCSV に変換するには、以下の手順を踏むことで実現できます。

  1. 商品名の列を name という名前でコピー
  2. 商品カテゴリ名を実際のIDにマッピングして product_category_id にコピー
  3. 商品コードの列を number という名前でコピー
  4. 定期商品かどうかを「はい」だったらtrue、「いいえ」だったらfalseにし、 is_recurring という名前でコピー
  5. 販売価格の列を sales_price という名前でコピー
  6. name, product_category_id, number, is_recurring, sales_price に絞り込み

これを レシピ 化すると、以下のようになります。

{
  "steps": [
    {
      "action": {
        "operation": "copy",
        "parameters": {
          "sourceColumn": "商品名",
          "targetColumn": "name"
        }
      }
    },
    {
      "action": {
        "operation": "map",
        "parameters": {
          "sourceColumn": "商品カテゴリ名",
          "targetColumn": "product_category_id",
          "map": {
            "アパレル": "1",
            "健康食品": "2"
          }
        }
      }
    },
    {
      "action": {
        "operation": "copy",
        "parameters": {
          "sourceColumn": "商品コード",
          "targetColumn": "number"
        }
      }
    },
    {
      "action": {
        "operation": "map",
        "parameters": {
          "sourceColumn": "定期商品かどうか",
          "targetColumn": "is_recurring",
          "map": {
            "はい": 1,
            "いいえ": 0
          }
        }
      }
    },
    {
      "action": {
        "operation": "copy",
        "parameters": {
          "sourceColumn": "販売価格",
          "targetColumn": "sales_price"
        }
      }
    },
    {
      "Action": {
        "Operation": "remain",
        "Parameters": {
          "targetColumns": "[\"name\",\"product_category_id\",\"number\",\"is_recurring\",\"sales_price\"]"
        }
      }
    }
  ]
}

これを各案件ごとに実装することで、先程挙げた4つの条件

  • Rubyスクリプトよりも高速であること
  • コストが安いこと
  • 案件によるイレギュラーな加工でも自分たちでコントロールできること
  • ノーコードツールを実現することで単純な処理にエンジニア工数を使わないようにすること

を満たすことができました。
また高速化については、

  • スクリプトのみ
  • レシピ + スクリプト

の両者を比較したところ、半分くらいの時間で移行業務を終えられるようになりました。
実測値では、スクリプトのみで6時間、レシピ + スクリプトで3-4時間くらいです。

まとめ

今回は移行業務のさらなる高速化/効率化を目指し、 データの加工とインポートを切り離し ました。
さらに レシピ という概念を取り入れて、データの加工そのものを高速化しました。
次回はデータの加工とインポートの実行環境の課題に触れつつ、コンテナ化について解説していきます。

SUPER STUDIOの採用について

SUPER STUDIOでは、エンジニアを採用しています。
少しでも興味がありましたら、以下をご覧ください。
https://hrmos.co/pages/superstudio/jobs/0000400
https://hrmos.co/pages/superstudio/jobs/0000404

昨年12月に9期目を迎えたSUPER STUDIOのキックオフイベントで社内表彰されたエンジニア受賞インタビュー記事です。よりSUPER STUDIOのエンジニア組織を理解できる内容となっておりますので、ご一読ください。
https://www.wantedly.com/companies/super-studio/post_articles/497997
https://www.wantedly.com/companies/super-studio/post_articles/487617

SUPER STUDIOテックブログ

Discussion