Javaプログラマの為のGAE/Py bulkloader - 引数指定無しでbulkloader実行 -

bulkloaderする度に長ったらしい引数を入力するのが嫌、 またはKind毎のloaderクラス毎に起動構成設定するのが嫌な僕の為に。

要は、appcfg.pyに渡すコマンドライン引数をプログラム内で作って、実際の処理に渡すってだけ。 appcfg.py内の処理は、AppCfgというクラスがほぼ全て行っているので、このクラスを直接使います。

PYTHONPATH設定

Eclipse PydevプラグインのGAE/Pyプロジェクトデフォルト設定では、 PYTHONPATHにantlr3へのパスが設定されていないので、 AppCfgクラスをimportした時にエラーになります。

まず初めに、antlr3にパスを通しておきます。 antlr3はDjangoとかと同じディレクトリにあります。

f:id:zetta1985:20100126225917j:image

2010-02-22 追記:

SDK 1.3.1以上の場合、他にもパスに追加する必要があるモジュールがあります 詳細は->高卒文系プログラマの日常 by zetta1985

appcfg実行スクリプト

環境やbulkloaderに渡したい引数によって内容は変わりますが、 だいたいこんな感じのスクリプトでいけると思います。

run.py

import sys
import os
from zetta1985 import sample
from google.appengine.tools import appcfg

def Load(loaderPath, kindName, email):
    argv = [os.path.abspath(loaderPath)
            , "upload_data"
            , "--config_file=" + os.path.abspath(loaderPath)
            , "--filename=" + os.path.dirname(loaderPath) + "/data.csv"
            , "--kind=" + kindName]

    if len(email) > 0:
      argv.append("--email=" + email)

    while(True):
        input = raw_input("Is the development server targeted? (y/n/c) :")
        if (input == "y"):
            argv.append("--url=http://localhost:8080/remote_api")
            break;
        elif (input == "n"):
            break;
        elif (input == "c"):
            print "Processing was interrupted."
            sys.exit(1)

    argv.append(os.path.dirname(sample.__file__))
    _AppRun(argv)


def _AppRun(argv):
    try:
        result = appcfg.AppCfgApp(argv).Run()
        if result:
            sys.exit(result)
    except KeyboardInterrupt:
        appcfg.StatusUpdate('Interrupted.')
        sys.exit(1)

Loader関数を呼び出すloaderクラスと同じパッケージにあるdata.csvをbulkloadします。 アップロード先を実行時に標準入力で設定できるようにしてみました。

_AppRun(argv)は、ほぼappCfg.pyのmainと同じコードです。

app.yamlの場所の解決にはsample.pyというスクリプトファイルを同じディレクトリに置いといて、 os.path.dirname(sample.__file__)でapp.yamlのディレクトリを取得してます。

・・・が、app.yamlをpythonスクリプトと同ディレクトリに置いておくのは、 自分でやっといてなんですがアリなんですかね?w

2010-02-22 追記:

ナシですw 詳細は->高卒文系プログラマの日常 by zetta1985

loaderクラス

前回のloader.pyに以下を追記します。

def main():
    from bulkload.core.run import Load
    Load(__file__, "Data", "zetta1985")

if __name__ == '__main__':
    main()

このloader.pyをコンテキストメニューなりショートカットキーなりで起動すれば、 bulkloaderを実行できます。

現在、GAE/Jで定義したKindをダウンロード・アップデートしたりと色々試してます。 気になるのは、Java-Python間のデータ型の変換ですね。

もう少し調べたら、そこら辺をブログでまとめたいと思います。

このエントリーをはてなブックマークに追加
comments powered by Disqus