Google App Engineで、Data Storeにデータをまとめてアップロードしたいことがあります。データベースのデータをまとめてアップロードするような操作です。

方法は、次のページに詳細に書かれています。

データのアップロード

appcfg.py コマンドと、アップロード時の変換に使用するローダ クラスを一緒に使用するような方法です。

しかし、ここに書かれている手順をそのまま実行すると、次のようなエラーが発生します。

[ERROR?? ] Error in Thread-9: ‘ascii’ codec can’t decode byte 0xe3 in position 0: ordinal not in range(128)

メッセージ自体は、Python で日本語を扱おうとするとしばしば発生するエラーですが、これが appcfg.py コマンドを使用するときにも発生します。アップロードするCSVに、日本語が含まれていると発生します。

解決するには、ローダー クラスでUnicodeの問題を吸収すればよいです。先のページに書かれているサンプルを、次のように書き換えます。

# -*- coding: utf-8 -*-
import sys
sys.path.append('/somewhere/mysources/')

from google.appengine.tools import bulkloader
from models import myModel

class DBLoader(bulkloader.Loader):
  def __init__(self):
  bulkloader.Loader.__init__(self, 'myModel',
  [('field1', lambda x: unicode(x,'utf-8','ignore')),
  ('field2', lambda x: unicode(x,'utf-8','ignore')),
  ('field3', lambda x: unicode(x,'utf-8','ignore'))])

loaders = [DBLoader]

クラスの名前の違いやモデルの違いなどは無視してください。ポイントは、文字列をそのまま渡さずに、unicode() で明示的にUTF-8に変換しているところです。これで、エラーなくアップロードできます。