2008-10-18

Google App EngineでModelのgetでKindError

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク
Google App EngineであるModelのgetをkeyオブジェクトを利用して行おうとしてKindErrorが出た時の対処メモです。
結論的には自分の記述ミスなのですが、しばらく原因がつかめずに苦労しました。

出たエラーは

File "・・・..\google\appengine\ext\db\__init__.py", line 759, in get
(instance.kind(), cls.kind()))
KindError: Kind 'MyModel' is not a subclass of kind 'MyModel'

でした。
同じモデルなのに種類が違うってどういうこと?
と思ったわけです。
エラーをraiseしているGoogle App Engineの該当部分のソースは、

for instance in instances:
if not(instance is None or isinstance(instance, cls)):
raise KindError('Kind %r is not a subclass of kind %r' %
(instance.kind(), cls.kind()))

ということで確かにkey値で取得したオブジェクトが想定したクラスのオブジェクトでないときに起こるエラーでした。

自分のコード内ここでやっているようにkind()を利用して調べたら確かに同じ。
そして確かにisinstanceはFalseになっている。

どういうこと?
としばらく悩んでいました。

Pythonをちゃんと知っていれば、すぐに分かったことなのでしょうが
Pythonの仕組みでオブジェクトのクラスを調べる方法として、きちんと
aaa.__class__
というものがあることに気づいて調べてみるとそれぞれ
ddddir.MyModel
MyModel
になっていて、確かに違うことがわかりました。

作成したアプリケーションではddddirディレクトリもファイルを探す対象として以下のようなことをしていました。

import sys
EXTRA_PATHS = [
os.path.join('ddddir'),
]
sys.path = EXTRA_PATHS + sys.path

そして作成したアプリケーションはいくつかのファイルで構成されているのですが、
ある2箇所で同じモデルを定義したファイルを読み込むときに
片方は、
from models import MyModel
としてもう片方が
from ddddir.models import MyModel
としていたためにおきていることが分かりました。

これを統一することで無事にKindErrorが消えました。

まだまだPythonの基本的なことがわかってなさそうな感じです。