PigのPython UDFを試してみた

PythonでUDFが書けるので試してみた。

日付の差を計算するUDFを書いてみる

とりあえず、日付の差を計算するUDFを書いてみた。

udf.py

@outputSchemaで、出力のスキーマを書いて、あとは普通に書く。

#!/usr/bin/env python

import time

@outputSchema("datediff:int")
def DateDiff(a,b):
  a_time = time.mktime(time.strptime(a,'%Y-%m-%d'))
  b_time = time.mktime(time.strptime(b,'%Y-%m-%d'))
  return int( (a_time - b_time) / 86400 )
date_diff_sample.pig

Register 'udf.py' using jython as myfuncs って感じで記述すると、Pythonで定義したDateDiff関数を、myfuncs.DateDiffで使う事が出来る。

Register 'udf.py' using jython as myfuncs;

A = load 'dummy';
A = foreach A generate myfuncs.DateDiff('2012-12-12','2012-12-01');
dump A;
実行

$ pig -f date_diff_sample.pig

...

(11)

注意点

Pythonで書いたUDFは、カレントディレクトリにそのファイルが無いと動かない。
なので、例えば、以下のような感じで書くとエラーになる。

Register '/path/to/udf.py' using jython as myfuncs;

...

そこで、以下のような簡単なスクリプトを書き、どこからでも作成したUDFを使えるようにする。

  • pig-tool
#!/usr/bin/perl -w                                                                                                                                   

use strict;
use Cwd;

my $pig_exec_dir = '/path/to/pig-udf-dir'; # UDFを置いてるディレクトリ
my $wd = Cwd::getcwd();

# -fと-mオプションで指定されたパスが相対パスの場合、絶対パスに書き換える
my @arr;
while (my $opt = shift @ARGV) {
    if( ($opt eq '-m' || $opt eq '-param_file') ||
        ($opt eq '-f' || $opt eq '-file') ){
        my $file = shift @ARGV;
        die ('No exist file: $file') unless -e $file;
        $file = "$wd/$file" unless $file =~ m|^/| || $file =~ m|^~|;
        $opt = "$opt $file";
    }
    push @arr, $opt;
}

# UDFが置いてるディレクトリに移動してpigを実行
chdir $pig_exec_dir;
`pig @arr`;
  • 実行

$ pig-tool -f hogehoge.pig

TokyoApache.pigについて

TokyoApache.PigというPigのコミュニティも作成したので、興味のある方は是非ご参加下さい!
年明けくらいから活動したいなと思っています!