App Engine NDBからGoogle Cloud NDBへの移行

GAEのスタンダード環境のPython2で作ったアプリをPython3に移行するための前準備。
Python2でしか動かないApp Engine NDB(Python2版 NDBという表記もあり)からPython2/3で動くGoogle Cloud NDBに移行する。

以下参考ドキュメント。

Google Cloud NDBはGAEに限らず動作するようになったため、GAEに依存するレガシーなAPIは削除されている。
が、互換性はけっこう維持されていて少し書き換えれば動くといったかんじ。

NDBクライアントのインスタンスが必要

これがもっとも重要な違いで必須の修正。

t = Test(name="hoge")
t.put()

としていたものを以下のようにNDBのClientを使ったものにする。

client = ndb.Client()
with client.context() as context:
    t = Test(name="hoge")
    t.put()

全面的に書き換える必要あり。
しかし書き換え自体は単純作業で終わるレベル。

コンテキストはスレッドセーフではないので複数のスレッドを使う場合にはスレッドごとにコンテキストを作成する必要があるといった注意点があるが、スレッドを使っていなければ関係ない。

代替手段に書き換える必要があるもの

ほか以下に該当するものがある場合は書き換える必要がある。なければ何もしなくていい。

Keyモジュール

Keyモジュールの以下のメソッドは削除された。

  • Key.from_old_key
  • Key.to_old_key

modelモジュール

modelモジュールの以下のメソッドは削除された。

  • get_indexes
  • get_indexes_async

Properties

モデルのプロパティの定義に以下のような違いがある。

  • BlogProperty: 常に_compressedが設定されていたが、明示的に渡された場合のみ設定するようになった
  • JsonProperty: 常に_json_typeが設定されていたが、明示的に渡された場合のみ設定するようになった
  • DateTimeProperty: 常に_auto_nowと_auto_now_addが設定されていたが、明示的に渡された場合のみ設定するようになった
  • TextProperty: indexed=Trueがサポートされなくなった。インデックスをつけることはできない
  • StringProperty: indexed=Falseがサポートされなくなった。常にインデックスされる(インデックスをつけないということができない)
  • Property: 以前はunicodeとstrを名前に使うことができていたが、今はstrのみ

QueryOptions and Query Order

  • google.appengine.datastore.datastore_rpc.Configuration => google.cloud.ndb.query.QueryOptions を代わりに使う
  • google.appengine.datastore.datastore_query.Order => ndb.query.PropertyOrder を代わりに使う

MessageProperty and EnumProperty

Google Protocol RPC Library(protorpc)に依存しているため削除された。

Tasklets

タスクレット(非同期処理の際に利用するコード片)を書くときにReturn例外は不要となり通常のreturnで良くなった。
旧来の書き方はまだ動作するが非推奨。

また以下のメソッドは実装されていない。

  • add_flow_exception
  • make_context
  • make_default_context
  • QueueFuture
  • ReducedFuture
  • SerialQueueFuture
  • set_context

ndb.utils

ndbutilsは削除された。

Python3の新機能によって代替できるようになったことやndbの実装の違いによるもの。

Exceptions

App Engineのレガシーな例外は利用できないが以下のようにバックポートできる。

from ndb.exceptions import BadRequestError, BadArgumentError

Datastore API

現在のDataStoreと旧来のApp Engine DataStoreの公開APIには互換性がある。
しかし古いNDBライブラリには非公開のAPIに依存して実装していたものがいくつかあり、それらの機能は動作しない。

  • ModelAdapter
  • Property._db_get_value, Property._db_set_value.
  • Property._db_set_compressed_meaning and Property._db_set_uncompressed_meaning.
  • Model._deserialize and Model._serialize.
  • model.make_connection.

Default Namespace

デフォルトのNamespaceの設定にnamespacemanagerが利用されていたが、クライアントをインスタンス化する際の引数として渡すように方式が変わった。

client=ndb.Client(namespace="my namespace")

Django Middleware

GAE版のndbに含まれていたDjangoミドルウェアは廃止された。
Djangoの新機能で簡単に独自のミドルウェアを作成できる。