はてだBlog(仮称)

私的なブログど真ん中のつもりでしたが、気づけばWebサイト系のアプリケーション開発周りで感じたこと寄りの自分メモなどをつれづれ述べています。2020年6月現在、Elasticsearch、pandas、CMSなどに関する話題が多めです。...ですが、だんだんとより私的なプログラムのスニペット置き場になりつつあります。ブログで述べている内容は所属組織で販売している製品などに関するものではなく、また所属する組織の見解を代表するものではありません。

PandasをElasticsearch検索インデクサープレ処理ETLに見立てた場合の「設計の共有」のためのモジュールファイル分割・分配方針

はじめに

最近Python、Pandasに入門していろいろ遊びながら、ETLにおける「設計の共有」が捗る&しかけってなんだろうなと思案しております。

ETLは汚れ仕事も多いので、他の分野以上にある種のスパゲティ化しがちで、実際はそうではなくとも、時が経ってなんでこうしているだっけというのが分かりにくいものだと思います。

そんななかで、関数やライブラリなどプログラムの共有やプログラミング効率化という面もないではないですが、あくまで「設計の共有」です。

これが結論!と断言するほどでもないのですが、このブログでもうっすらテーマにしているElasticsearch周辺や検索サイトにおいて、少しこじれた元情報をよろしく検索しやすいカタチに加工するインデクサーの前処理的なETLの場合、これぐらいがいいんじゃないかという例を編み出して見ましたので、それをぶちまけてみます。

DataFrameを軸にしたモジュールファイルの分割(関数の分配)による駆動

ということで、コレです。

f:id:azotar:20190513210617p:plain

余裕があれば、これのイメージにそってオレオレElasticsearch検索インデクサープレ処理のPandasのコードを公開できたらと思っていますが、現在したためているものはイメージ例のものとはいえもう一声必要かなと思って控えております。

...ので、以下、ちょっとだけ解説。

これは何かというと...

特にフレームワークなどは考えるに至りませんでした。もともとオレオレルールとか僕の考えたさいきょうのなんとかに近いのですが、重厚なものは結局向かなくて、モジュールファイルへの分配ルールです。

ちょっとだけ解説

私がキモだと思っているのは、下手にオブジェクトやエンティティ、あるいはビジネスやソリューションの単位でクラス化やモジュール分割するのではなくて、上記のように取り扱うデータの型、特にDataFrameとの関わり方によって、同じ立場のものを同じモジュールファイルに分配してくように采配するということです。

(以下、項番号と上述のイメージ絵の項番号は対応させています。)

  1. DataFrameにあまり関係ない、そもそも処理を走らせるための制御は、「ランナー」とする。また、契機となるデータもしくはキュー情報などはここで制御する。
  2. 生のDataFrameのカタチは意識せず、インプットとアウトプット、および対象とするデータ変換のビジネスフローのみ意識する「ジョブ」として処理を定義する。
  3. インプットのデータをストレージから取り出して、データパイプラインの本流や太めの支流を流れるデータセットを表すDataFrameのカタチを整える処理を「Dataset」として定義する。 → オンラインアプリなどではClassになることも多いケースだが、おそらくDataFrameとして抽象化した方がETLの場合はうまくいく。もし手グセでClassにしてしまった場合はETLには持ち込まない方が良い類の思い込みが入っているかもしれない。なお、実際にストレージとの接続などは、7のAdapterに配置して、インフラ系のコードを追い出す。
  4. ビジネスルールを外部から受け取って、(2のジョブのパイプライン上を流れる主流の)DataFrameについて、次項5の関数をもしくは次項5の関数を組み合わせてラッパー関数を作って、(通常は)DataFrameの全項目に宣言的に変換をほどこしていく処理を関数としてこのモジュールファイルに固める。今回の中では、他のものに比べると、対象とする変換のサブドメインが別の場合は、さらに別ファイルにする。... ので、これらは XxxPlugins.pyのような名前にする。
  5. 抽象的なDataFrameをインプットもしくはアウトプットにする、単独で動作できるユーティリティ関数群をモジュールにまとめる。前項と後述の文字列Utilsとの住み分けがポイント。
  6. 文字列操作、プリミティブな型に関するなんらかの操作の関数をまとめる→Utils.pyモジュールファイル。ここにはDataFrameを引数や戻り値に入れる関数は配置しない。
  7. ストレージなどからデータをロードするといったインフラ層のコード。ただし、今回はPandasを利用しているストーリーなので、DataFrameを返すものやDataFrameを受け取るものはここにいるが、DataFrameのカラム名は意識しないで処理するタイプのもののみとなっている(ハズ)。

つまるところ、ETLにおいては、Pandasで言う所のDataFrameのような二次元の表のデータのシェイプをこねこねしていくというところこそが共通のアプリケーションドメインであり、DataFrameを通してもの事を見た方が、コードの見通しとともに設計のエッセンスが可視化されやすくなり、設計の共有に繋がるという主張なのでした。

また、加えて、結果的にプログラムコードの記述の効率化や適度な疎結合も進むのではないか、というある意味当たり前かもしれないという気づきでした。

以上です。