2017-01-11 10 views
2

私は、Google App Engineを使用してプロトタイプインベントリアプリケーションを開発してきました。私は最近、古いDBデータストアライブラリを使用して新しいNDBライブラリを使用するように切り替えました。機能はすばらしかったですが、自分のエンティティの1つに変更を加えると、突然NDBは "メタデータ"エンティティ。ここでは、エンティティの記述は(私が行った変更は、「inv_posid」と「inv_lastchange」プロパティを追加するために、主要な何もなかった)です:Google App Engine __metadata__プロパティを作成するNDB

class Inventory(ndb.Model): 
    inv_product = ndb.KeyProperty(kind = Product) 
    inv_prdcr_name = ndb.StringProperty(default="") 
    inv_product_type = ndb.StringProperty(default="") 
    inv_product_name = ndb.StringProperty(default="") 
    inv_product_year = ndb.IntegerProperty(default=0) 
    inv_count = ndb.IntegerProperty(default=0) 
    inv_price = ndb.IntegerProperty(default=0) 
    inv_glass_price = ndb.IntegerProperty(default=0) 
    inv_bin = ndb.StringProperty(default="") 
    inv_posid = ndb.StringProperty(default="") 
    inv_lastchange = ndb.FloatProperty(default=0.0) 

新しいプロパティを追加することで、私は「inv_lastchangeを使用する私のクエリを変更するためのものNDBは決して適切なプロパティが含まれていない結果のエンティティを決して含んでいないので、私のデータストアをすばやくスキャンして、すべてのエンティティにプロパティを適切に追加したいと考えました。だから、ここで私がやったことだ:

... 
@ndb.tasklet 
def fixInventory(invitem): 
    invitem.inv_posid = "" 
    invitem.inv_lastchange = 0.0 
    invkey = yield invitem.put_async() 

inventory = Inventory.query() 
output = inventory.map(fixInventory) 

が、私はタスクレットで遊んと非同期呼び出しが働いたかを確認するためにきちんとしただろうと思いました。しかし、その後、データストアビューア(ローカルデータストア上)を見ると、この新しい「 メタデータ」というプロパティが表示されました。これはNDBが必要とするものであると想定していたため、それの何か。

まで、私は私のインベントリ項目のいずれかを更新しようとした次回は、私はこのエラーを得た:

File "/Programming/VirtualCellar/server/virtsom.py", line 2118, in get 
    inventory.put() 
    File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/ndb/model.py", line 3432, in _put 
    return self._put_async(**ctx_options).get_result() 
    File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/ndb/tasklets.py", line 326, in get_result 
    self.check_success() 
    File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/ndb/tasklets.py", line 369, in _help_tasklet_along 
    value = gen.throw(exc.__class__, exc, tb) 
    File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/ndb/context.py", line 810, in put 
    key = yield self._put_batcher.add(entity, options) 
    File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/ndb/tasklets.py", line 369, in _help_tasklet_along 
    value = gen.throw(exc.__class__, exc, tb) 
    File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/ndb/context.py", line 343, in _put_tasklet 
    keys = yield self._conn.async_put(options, datastore_entities) 
    File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/ndb/tasklets.py", line 455, in _on_rpc_completion 
    result = rpc.get_result() 
    File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/api/apiproxy_stub_map.py", line 613, in get_result 
    return self.__get_result_hook(self) 
    File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/datastore/datastore_rpc.py", line 1882, in __put_hook 
    self.check_rpc_success(rpc) 
    File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/datastore/datastore_rpc.py", line 1373, in check_rpc_success 
    raise _ToDatastoreError(err) 
BadRequestError: cannot store entity with reserved property name '__metadata__' 

だから何が起きているのでしょうか?私がここで忘れていることはありますか? 「メタデータ」のプロパティは何らかの形で隠れているか保護されているように見えますが、通常のプロパティと同様に追加されているため、エンティティに他のセーブを禁止しています。誰もこれを前に走っている?

+0

「メタデータ」プロパティを自動的に作成する 'ndb'について聞いたことはありません。あなたはその物件が以前に存在しなかったことは確かですか?このプロパティがポップアップしたときに、エンティティをどのくらい変更しましたか? –

答えて

2

プロパティは、データストアに保存され、データストアから読み取られるときに削除されるとき、エンティティに追加されます。これはgoogle/appengine/datastore/datastore_stub_util.py_ToStorageEntity_FromStorageEntityの関数で行われます。

おそらく、内部エラーによってエンティティが何らかの形で破損している可能性があります。

エンティティインスタンスの_properties dictと保存から__metadata__プロパティを削除すると、回復することができます。例えば

for inv in Inventory.query(): 
    del inv._properties['__metadata__'] 
    inv.put() 

(事故に対する予防策として、これをしようとする前に、ローカルのデータストアファイルたぶんバックアップ)。 snakecharmerbが、私は私のデータストアビューアはまた私に__metadata__性を示すた理由を見て始めて、それは私が以前にGoogleのApp EngineのSDKの古いバージョンをダウンロードしていたことが判明し、上記の言ったことに基づいて、だから、

+0

'ndb'は_で始まるプロパティを許可しませんが、' db'はそれを行いません。あなたは 'db'で修正を試みるかもしれません。 –

+0

@ JeffO'Neill私は間違いがあるかもしれませんが、過去にこれを打ったことの微妙な記憶を持っていますが、dbに落とすことなくそれを固定しました。うまくいけば、OPは報告し、何が起こるか教えてくれるでしょう。 – snakecharmerb

2

、何らかの理由で、私の環境変数は、SDKの最新バージョンを2〜3回インストールしたにもかかわらず、古いバージョンを指していました。私は私のマシンからGoogleアプリケーションエンジンSDKのすべての痕跡を拭き取り、ゼロからSDKを再インストールしました。voila!__metadata__のプロパティは、データストアのビューアと自分のコードの両方で削除されました。私の現在の仮説は、同じ方法でgoogle/appengine/datastore/datastore_stub_util.pyファイルの古いバージョンが__metadata__プロパティを処理していないということです。

おかげで助けをそんなに!

関連する問題