GAEデータストアのModelクラスのインスタンスからそのkey_nameを取得する方法について
これまでModel、Key、Propertyの関係を理解しないままデータストアを使用していた事を改めて思い知りました。(^_^;)
下のような都道府県の面積と人口を記録するデータストアのエンティティがあるとします。
class Prefecture(db.Model): area = db.FloatProperty() population = db.IntegerProperty() pref1 = Prefecture(key_name='Tokyo', area=2188.67, population=13269061) pref1.put() pref2 = Prefecture(key_name='Chiba', area=5156.61, population=6192785) pref2.put()
ここから人口が1000万人以上の都道府県を取得し、表示したい場合下のようなクエリを使うと思います。
query = Prefecture.all().filter('population >', 10000000).order('-population')
あとはここから都道府県名すなわちkey_nameを取得すればいいわけですが、この方法がわからずしばらく悩んでしまいました。
私はkey_nameをデータストア上でユニークであることが保証されている便利なプロパティの一種であるかのように使用していたので
for val in query: name = val.key_name
のようにkey_nameを取得しようとしてしまいました。これはAttributeErrorになります。
key_nameを取得するには次のように書く必要があります。
for val in query: name = val.key().name()
valはModelクラスのインスタンスでありval.key()が返すのはKeyクラスのインスタンスなのでkey_nameはval.key().name()で取得するということです。
要は「key_nameはプロパティの一種などではない」ということなのですがインスタンス作成時に下のようにプロパティと同列に引数で指定できるため思い違いをしていました。
pref1 = Prefecture(key_name='Tokyo', area=2188.67, population=13269061)
key_nameはそのエンティティを他のエンティティと区別するための識別子であるKeyオブジェクトの要素でありエンティティ自体のプロパティとは異なります。
このことはエンティティ、プロパティ、キー | Python の App Engine スタンダード環境 | Google Cloudに書かれています。
このページ目を通したはずだったのですが難しいことが書いてあるな〜という感じで理解できていませんでした。
今回の問題に当って改めて読んでみてやっとModel、Key、Propertyの関係が分かりました。