爬虫類嫌いのPython日記

爬虫類が大の苦手の筆者が、Pythonに挑戦。他にも、RubyやObjective-C、Google Appengine、Herokuなど色々とチャレンジしています。

bulkloadでCSVファイルを一括アップロード

app.yamlの編集

app.yamlに、以下のディレクティブを追記します。

builtins:
- remote_api: on

追記したら、デプロイします。

bulkloaderの設定

デプロイした設定を基に、bulkloader.yamlを自動生成します。

appcfg.py create_bulkloader_config <your application path> --filename=bulkloader.yaml

上記のコマンドが正常に終了すると、アプリケーションフォルダの中にbulkloader.yamlや各種ログファイル等が自動生成されます。

CSVファイルのアップロード

CSVファイルをアップロードするために、bulkloader.yamlを変更します。
基本的には、transformers:ディレクションを変更するだけで十分です。

transformers:
- kind: Sample
  connector: csv
  property_map:
    - property: user_id
      external_name: user_id
      import_transform: int
        
    - property: movie_id
      external_name: movie_id
      import_transform: int
        
    - property: rate
      external_name: rate
      import_transform: int
        
    - property: timestamp
      external_name: timestamp
      import_transform: int

ちなみに、アップロードするCSVファイルは、こんな感じです。

"user_id","movie_id","rate","timestamp"
196,242,3,881250949
186,302,3,891717742
22,377,1,878887116
244,51,2,880606923
166,346,1,886397596
298,474,4,884182806
115,265,2,881171488
253,465,5,891628467
305,451,3,886324817
6,86,3,883603013
62,257,2,879372434
286,1014,5,879781125
200,222,5,876042340
210,40,3,891035994
224,29,3,888104457

ポイントは、1行目のヘッダ部分です。
ここを、bulkloader.yamlで設定した名前と統一しないと、BalkLoadが成功しても、データストアの内容がになってしまうので要注意です。

appcfg.py upload_data <your application path> --config_file=bulkloader.yaml 
--filename=<upload CSV file> --kind=<kind name>

バグってた場合の一括削除

一括アップロードは出来るのですが、一括削除はできません。
数件のテストデータであれば、ダッシュボードのDatastore Viewerから20件単位で削除できますが、大量のデータを削除する場合は大変です。

そこで、今回はGoogle App Engineのアプリに以下の追記を行いました。

class DeleteHandler(webapp.RequestHandler):
    def get(self):
        q = db.GqlQuery("SELECT * FROM Sample")
        results = q.fetch(10000)
        db.delete(results)

これで、マッピングした任意のURLにアクセスする度に10000件ずつ削除してくれます。

class Sample(db.Model):
    user_id   = db.IntegerProperty()
    movie_id  = db.IntegerProperty()
    rate      = db.IntegerProperty()
    timestamp = db.IntegerProperty()

データプロパティを設定してやらないと、エラーになるようなので、設定しておきましょう。