2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Google Cloud PlatformAdvent Calendar 2017

Day 25

Datastoreのnamespaceを変更して複製するには?

Last updated at Posted at 2017-12-23

NamespaceごとにDatastoreを複製した

GCPのDatastoreにはnamespaceによってパーティションを作る機能があります。一つのnamespaceにあるものを丸ごと違うnamespaceに移す、というのはどのようにやればいいのか。やることがあったので書いておきます。

Namespaceを切り替えることはできない?

そもそも最初にやりたかったのは、datastoreに保存された全てのEntityのnamespaceを変更できないかということ。
ただ、どうやらできない?

Namespace is the part of the Key. So you can't change or copy all data from one namespace to another. As I understand all you can do is to fetch all objects from one namespace and create NEW objects with the same properties in another namespace.

というわけで、デフォルトのnamespaceから新しくnamespaceを切って丸ごとコピーする方法をやってみました。

namespace_manager

namespaceを変えるには、namespace_managerを使います。

import logging
from google.appengine.api import namespace_manager

#現在のnamespaceを知るには
current_namespace = namespace_manager.get_namespace()
# defaultは空
logging.debug(current_namespace)
# namespaceをnew_namespaceに設定
namespace_manager.set_namespace('new_namespace')
# 以下でput()したら設定したnamespaceで保存される

保存したいもエンテティはこんな形式だと仮定します。idはitemをそのまま使うということにしておきます。

class Item(ndb.Model, NDBMixin):
    item = ndb.StringProperty()
    message = ndb.StringProperty()

namespaceを変更した場所に丸ごと保存するには?

前のnamespaceの状態で、datastoreから引き出してきて、set_namespaceしたあとに保存します。

# 全件取得
items = Item.query().fetch()
# namespaceを変更
namespace_manager.set_namespace('new_namespace')
entities = (Category(
    id=item.item,
    item=item.item,
    message=item.message,
    ) for item in items)
# 一括保存
ndb.put_multi(entities)

parentキーも保存する場合

複数のカインド含めて丸ごと複製したいときに、parentキーを持っていたりすることもあります。その際には、もちろんですがキーリファレンスも作り直して保存してあげる必要があります。

class ChildItem(ndb.Model, NDBMixin):
    item = ndb.StringProperty()
children = ChildItem.query().fetch()
entities = (ChildItem(
    id=child.item,
    parent=ndb.Key(Item, item.key.parent().get().item),
    item=child.item,
    ) for child in children)
ndb.put_multi(entities)

こんな感じでやってみましたが、他にいい方法がありそうな気もします。。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?