投稿日:

GAE の Datastore の Timeout 対策


Google App Engine のデータストアって、よく Timeout しますよね。(;^ω^)
本日、単純な Model.get() が Timeout したので、さすがに我慢できなくてリトライするように変更してみました。何かの参考になればとコードをアップしておきまーす♪

 

※_original_func 関連のコードは別に無くても良いのですが、ローカルの開発環境ではコードの修正などに伴って問題が出ることがあるので、追加しています。たぶん本番環境では不要ですね。

なお、この変更にもし問題などが有りましたら、ご指摘頂けたら助かります!

 

 

投稿日:

GAE の Model の バリデーションの動作を変えてみた


GAE のデータストアでは、値をプロパティにセットした時点で、validate されてしまう為、次のような問題があります(少なくとも僕にとっては)。

  • 複数の属性に関係するバリデーションが実現できない。
  • 入力フォームの表示用等で空のインスタンスが欲しい時、インスタンス化された時点で validate されるので利用できない。

これらの回避の為に、バリデーション周りを以下のようにして変えてみました。

 

以下、簡単な解説です。

  • setattr(db.Property, ‘__set__’,……
    今回のキモ。db.Property クラスの __set__ デスクリプタ メソッドを上書きし、属性代入時のバリデーションをバイパスしています。GAE v1.2.6 において、Property の定義済み実装クラス群では、ReferenceProperty 以外は __set__ のオーバーライドがありません。ReferenceProperty は __set__ がオーバーライドされていますが、目的に対しては特に影響無いものでしたので、属性保存時のバリデーションの無効化は、とりあえずこれで OK!
  • BaseModel クラス
    GAE の db.Model をサブクラスを作成し validate メソッドを追加しています。validate メソッドは、Model インスタンスの全ての属性をバリデーションし、検出されたエラーを、errors に保存します。アプリケーションの Model は、この BaseModel を継承して作成し、保存の前には必ず、validate()(または is_valid)を呼んでください。
  • Errors/Error クラス
    エラー情報を処理するコンテナ。

 

以下のように利用します。

 

…とまあ、こんな感じです。

注意点として、Rails のように、put() などで自動的に validate はされません。必ず、is_valid の参照、または validate() の呼び出しが必要です。実装するのは簡単ですが、これぐらいで不便は無いと思うし、GAE 側の Model の今後の変更にもやや強いかと思っています。

…次はバリデーション エラーメッセージの日本語化ですね…。

 

 

投稿日:

WebOb の cookie と urllib.unquote 辺りで文字化けする問題


Google App Engine の webapp の仕様がちょっと気に入らなかったので、URLのディスパッチとコントローラー部分を自作していますが、Cookie をハンドルするメソッド回りで文字化けが発生して困ってました。

Request/Response オブジェクトには、WebOb を使いました。
で、クッキーに保存する値は、urllib.quote で url エンコードします。

で、読み出す時は、urllib.unquote でデコードします。

ところがこれだと日本語文字が文字化けするんですね…。

全てを utf-8 に統一しているので問題は無いつもりなんですが、色々やっても文字化けです。

散々悩んでようやく気付いたのが、request.cookies.get で取得した値が、unicode オブジェクトになっているということ!そして、urllib.unquote が unicode オブジェクトの入力を、正しく処理できないらしいということでした。

urllib.unquote の挙動については、itasukeさんのこちらの記事で教えて頂きました。例外が出ないので、なかなか気付けなかったみたいです(…言い訳でーす)。itasukeさんの記事によると、UTF-8 のまま unicode にされてしまうとか…。どうりで、文字化けしてしまうわけですね…。

で、WebOb の Request からの取得値を value.encode(‘raw_unicode_escape’) してstr にしてみたところ、文字化けは解消されました。

これを受けて、クッキーをハンドルしているクラスに、次の作業メソッドを追加。

もちろん、エンコード側も似たように作成。

というわけで、解決。

こんなことに3日も悩んだわけですが、
おかげさまで Python の文字コード周りの見通しが良くなりました♪*1