トレーディングカードゲーム「Magic:The Gathering」の攻略サイト MTG-Guild の 開発日誌です。 Google App Engine - Python で構築スタート! ・・・どうなることやら
2012年2月13日月曜日
2012年2月8日水曜日
SyntaxHighlighterを入れてみました
Google先生も古い情報ばかり教えてくるので、探し出すのに結構かかったのでメモ。
設定方法:
SyntaxHighlighter を Blogger で使えるようにするには、
以下のサイトを参考に設定すると良いです。
SyntaxHighlighterのグーグルBloggerでの使い方
http://yksmtmks.blogspot.com/2011/05/syntaxhighlighterblogger.html
SyntaxHighlighter 3.0 on Blogger
http://kenmemo.blogspot.com/2011/05/syntaxhighlighter-30-on-blogger.html
Yet Another How To Use SyntaxHighlighter in Blogger with Autoloader
http://ywafield.blogspot.com/2011/03/yet-another-how-to-use.html
なくても動くみたいですが、いちおう入れてます。
使い方のメモ:
エンコードはここが便利:
www.netyasun.com/syntaxhighlighter/source-escape.html
英語の読み書きを訓練するのが一番大事な気がする今日この頃です・・・。
設定方法:
SyntaxHighlighter を Blogger で使えるようにするには、
以下のサイトを参考に設定すると良いです。
SyntaxHighlighterのグーグルBloggerでの使い方
http://yksmtmks.blogspot.com/2011/05/syntaxhighlighterblogger.html
SyntaxHighlighter 3.0 on Blogger
http://kenmemo.blogspot.com/2011/05/syntaxhighlighter-30-on-blogger.html
Yet Another How To Use SyntaxHighlighter in Blogger with Autoloader
http://ywafield.blogspot.com/2011/03/yet-another-how-to-use.html
この一文SyntaxHighlighter.config.bloggerMode = true;
使い方のメモ:
www.netyasun.com/syntaxhighlighter/source-escape.html
英語の読み書きを訓練するのが一番大事な気がする今日この頃です・・・。
2012年2月7日火曜日
GoogleAppEngin(Python2.7)で、NDBによる非同期アクセスをお試し中
以下のサイトで、GAE/PのNDB(Next DB module)モジュールについて知りました。
https://sites.google.com/site/copypesouko/--manyuaru/datastore-plus-tutorial-ja
(ただ、今は【ここ】の情報が最新らしいですね)
全然ドキュメント読めていないのですが、(Python創始者のGuidoがせっせこ作っている)GAE/Pのデータストアで非同期アクセスを行う為のモジュールらしいですね。
(他にもコンテキスト処理?とかいろいろ出来るらしいけれど難しそうなので読んでません)
非同期にアクセスできるようにということは、
- 複数のテーブルへのアクセスを並列実行できるので、反応を改善できることがある。
(とはいえ、高価なデータストアに頻繁にアクセスする設計は間違っている気がします) - 書き込み結果を待たずにレスポンスを返せる。たとえば、ブログの更新のように、書き込みにほぼ成功するような更新なら、反応を早くできる。
具体的には、データストアとMemcacheへの更新を並行して実施することで、データストアへの書き込みを待たずにキャッシュを使って更新結果を参照させることができる。
ただ、この新しいモジュールではkey_nameを使えません(!)
from google.appengine.ext.ndb.model import (Model as _NdbModel,
transactional)
class Model(NdbModel):
u"""google.appengine.ext.db.Modelの動きを真似るラッピング
ぶっちゃけ、こんなラッピングはしないほうが良いと思います
"""
def __init__(self, **kwds):
_kwds = kwds.copy()
key_name = _kwds.get('key_name')
if key_name != None:
_kwds['id'] = key_name
del(_kwds['key_name'])
NdbModel.__init__(self, **_kwds)
@classmethod
def get_by_key_name(cls, key_name, **kwds):
return cls.get_by_id(id=key_name, parent=kwds.get('parent'))
@classmethod
@transactional
def insert_or_fail(cls, id_or_keyname, **kwds):
u"""挿入して挿入された値を返します。
キー重複は、何もせずにNullを返します。全然非同期じゃないし、動作未検証です。
"""
entity = cls.get_by_id(id=id_or_keyname, parent=kwds.get('parent'))
if entity is None:
entity = cls(id=id_or_keyname, **kwds)
entity.put()
return entity
return None
- google.appengine.ext.dbをgoogle.appengine.ext.ndbにすると新しいモジュールでなんとなく動く(だいたいのAPIは上位互換)
- key_nameとidの区別がなくなって、key_nameを使っていたところはidを使うようにAPIが変更されている
- 普通にput()とかすると、これまでどおりの処理が行われる(全然非同期じゃない)
- 非同期処理を行う場合は、
k1 = Key('モデル名', id)
f1 = k1.get_async() # これで、値の取得が開始される
<何か処理をする>
a1=f1.get_result() # 取得結果を受け取る
ということらしいです。(key_nameが無くなったことを知るだけで2時間くらい消費してしまった・・・。へこみました)
確かに、自動でidを振られた場合と 自分でkey_nameを指定した場合で、使うメソッドが違うのは格好が悪いので、このほうが良いですね。
だから、上の例みたいなラッピングはしないことがお勧めです(!)
普通にget_by_idで統一しましょう。
2012/02/25 追記:
あれ、でも別にNDB使わなくても、昔から非同期でデータストアにアクセスできるんですね・・・。
GAE/PのAsync Datastore APIの使い方
その他の追加の機能(yeildで非同期アクセスの結果を受け取る書き方や、taskletsとか)や、設計上の不合理、新バージョンを押し付けない、ってのがメインなんですね・・・。
うーん?別にそんなにNDBにこだわる必要もないような?
2012/03/05 追記:
ここの記事見るより、こっちを見ましょう!
http://najeira.blogspot.com/2012/02/google-app-engineapindb.html
2012年1月12日木曜日
GAE Python 2.7のテスト環境の構築について考えてみる
今のGAEだと、
from google.appengine.ext import testbed
とかからで、必要なスタブを読み込んでいけばいいんですね。
プロダクション環境のビッグテーブルを使ってテストしなくちゃいけないほどハードなテストはしないよていなので、GAETestBaseは移植しないことにしました。
gaeunitみたいな、プロダクション環境でテストを動かす仕組みはあったほうが良い気がしますね。
今の案では、
Python2.7の環境なら、unittestで、かなりいけるはず。noseとかいらないかもしんない。
webtest と BeautifulSoup は リクエストを投げて帰ってくるレスポンスの内容をテストする為にいるはず。
アプリのバージョンでnamespaceを分けるようにすれば、アプリを公開後もプロダクション環境でテストを走らせることは可能なはず。
ただ、そうした場合、バージョン間のデータのコピーとかを簡単にできるように環境を整えるのと、Seleniumのテスト開始時にデータストアを初期化するような仕組みがほしくなりますね。
んー面倒だから、プロダクション環境でのテストは後回しかな。
TDDで開発するには、ローカル環境でテストできれば十分だし。
from google.appengine.ext import testbed
とかからで、必要なスタブを読み込んでいけばいいんですね。
プロダクション環境のビッグテーブルを使ってテストしなくちゃいけないほどハードなテストはしないよていなので、GAETestBaseは移植しないことにしました。
gaeunitみたいな、プロダクション環境でテストを動かす仕組みはあったほうが良い気がしますね。
今の案では、
- ローカル環境:unittest + testbed + webtest + BeautifulSoupでテスト。
- プロダクション環境:Seleniumでテスト
Python2.7の環境なら、unittestで、かなりいけるはず。noseとかいらないかもしんない。
webtest と BeautifulSoup は リクエストを投げて帰ってくるレスポンスの内容をテストする為にいるはず。
アプリのバージョンでnamespaceを分けるようにすれば、アプリを公開後もプロダクション環境でテストを走らせることは可能なはず。
ただ、そうした場合、バージョン間のデータのコピーとかを簡単にできるように環境を整えるのと、Seleniumのテスト開始時にデータストアを初期化するような仕組みがほしくなりますね。
んー面倒だから、プロダクション環境でのテストは後回しかな。
TDDで開発するには、ローカル環境でテストできれば十分だし。
2012年1月5日木曜日
GoogleAppEngineでjinja2を使う
jinja2は日本語のドキュメントの出来が良いし、Sphinxでも使えるので、個人的にテンプレートエンジンとしては一択だと思っています。
GAE/P 2.7では一部のサードパーティのライブラリも使えるのですが、そこにjinja2も含まれています。使用する場合は、こんな感じの記述をapp.yamlに加えましょう。
libraries:
- name: markupsafe
version: latest
- name: setuptools
version: latest
- name: jinja2
version: latest
バージョン指定を推す流派もありますが、私は新しいもの好きなのでlatestを推します。問題がおきたらバージョンを指定すれば良いんじゃないかと。
追加するライブラリはjinja2だけでも良いけど、パフォーマンスとかを考えるとmarkupsafeは入れたほうが良いんじゃないかと。
ローカルで動かす場合は、SDKには上記のライブラリはないので、入れとく必要ありますね。
といっても、setuptoolsは入れているでしょうから、
easy_install jinja2
easy_install markupsafe
ってやるだけでしょうけど。
テンプレートを毎回ロードするのが嫌なので、ロードしたテンプレートをグローバルな辞書に登録してキャッシュさせているのですが、jinja2はデフォでキャッシュ機能があるらしいので、あんまり意味ないのかな?
(デフォのキャッシュにはサイズに制限があるそうだけれど、その制限はどれくらいなのか、また、制限を解除できるのかは、もうちょっと調べよう)
あと、全然話は変わりますが、2.5で使っていたGAETestBaseとか、GAEUnitとかは、Python2.7の環境だと動かないみたいですね。参考にしながらテスト用のフレームワークもどきを揃えてみるかなぁ。
そういうのがないと自動テストとかきつくてやっていられないと思うのだけれど・・・、料金改定でみんなGAE/P使ってないのかな?
登録:
投稿 (Atom)