ちょいメモ。
ndb の "Repeated Property" について、仕様として気になることをちょっと調べてまとめてみました。
はじめに (Repeated Propertyって?)
ndb のプロパティに repeated=True
をつけたものを Repeated Property といい、
プロパティに配列を渡して値を複数保存することができます。
例
class MyModel(ndb.Model): items = ndb.StringProperty(repeated=True) key = ndb.Key(MyModel, 'test') obj = MyModel(key=key, items=['item1', 'item2']) obj.put() print obj
上記の結果は
MyModel(key=Key('MyModel', 'test'), items=[u'item1', u'item2'])
となります。また、
key = ndb.Key(MyModel, 'test') obj = key.get() obj.items.append('new_item') obj.put()
のように、通常の python の list と同じように扱うことができます。
気になったこと
- 初期値は
None
?- 初期値というか、何も指定せずにエンティティを保存した時、次にそれを取り出したら
None
が入ってるんでしょうか。
- 初期値というか、何も指定せずにエンティティを保存した時、次にそれを取り出したら
None
を指定して保存するとどうなるのか?- 1とも関連しますが、今度は明示的に
None
を指定して保存した場合、次に取り出したらどうなるか。
- 1とも関連しますが、今度は明示的に
- set を渡しても保存できるのか?
順番に試してみます。
なお、以下のコードは全部開発サーバーのコンソール(http://localhost:8000/console) で試してます。
1. 初期値は None
?
実行したコード
class MyModel(ndb.Model): item = ndb.StringProperty() items = ndb.StringProperty(repeated=True) key = ndb.Key(MyModel, 'test') obj = MyModel(key=key) print 'item: %r' % obj.item print 'items: %r' % obj.items obj.put() obj = key.get() print 'item: %r' % obj.item print 'items: %r' % obj.items
実行結果
item: None items: [] item: None items: []
結論
Repeated Property は何も指定しないと []
(空のlist) がセットされる。
2. None
を指定して保存するとどうなるのか?
実行したコード
class MyModel(ndb.Model): item = ndb.StringProperty() items = ndb.StringProperty(repeated=True) key = ndb.Key(MyModel, 'test') obj = MyModel(key=key) obj.items = None obj.put() obj = key.get() print 'items: %r' % obj.items
実行結果
なんかエラーでた。
Traceback (most recent call last): File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/tools/devappserver2/python/request_handler.py", line 225, in handle_interactive_request exec(compiled_code, self._command_globals) File "<string>", line 30, in <module> File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/ndb/model.py", line 1363, in __set__ self._set_value(entity, value) File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/ndb/model.py", line 1104, in _set_value (value,)) BadValueError: Expected list or tuple, got None
結論
そもそも保存ができない。BadValueError になる。
3. set を渡しても保存できるのか?
実行したコード
class MyModel(ndb.Model): item = ndb.StringProperty() items = ndb.StringProperty(repeated=True) key = ndb.Key(MyModel, 'test') obj = MyModel(key=key) obj.items = set(['1', '2']) obj.put() obj = key.get() print 'items: %r' % obj.items
実行結果
items: [u'1', u'2']
結論
OK。
念のため tuple も試したけど問題ありませんでした。
まとめ
- 初期値は
None
?[]
(空の list) がセットされる
None
を指定して保存するとどうなるのか?- そもそも保存ができない。BadValueError になる
- set を渡しても保存できるのか?
- set も tuple もOK