3

オブジェクトが最初に作成されたときに更新されないComputedProperty内部に aがあります。StructuredProperty

オブジェクトを作成してaddress_components_asciiも保存されません。このフィールドは、Datastore Viewer にはまったく表示されません。しかし、私がget()すぐput()に(何も変更しなくても)再び実行するとComputedProperty、期待どおりに動作します。address_componentsフィールドは正常に動作します。

データベースをクリアし、データベース フォルダ全体を削除しようとしましたが、成功しませんでした。

Windows 7 でローカル開発サーバーを使用しています。GAE でテストしていません。


コードは次のとおりです。

class Item(ndb.Model):
    location = ndb.StructuredProperty(Location)

内側の Location クラス:

class Location(ndb.Model):
    address_components = ndb.StringProperty(repeated=True)  # array of names of parent areas, from smallest to largest
    address_components_ascii = ndb.ComputedProperty(lambda self: [normalize(part) for part in self.address_components], repeated=True)

正規化機能

def normalize(s):
    return unicodedata.normalize('NFKD', s.decode("utf-8").lower()).encode('ASCII', 'ignore')

フィールドの例address_components:

[u'114B', u'Drottninggatan', u'Norrmalm', u'Stockholm', u'Stockholm', u'Stockholms l\xe4n', u'Sverige']

およびaddress_components_asciiフィールド、2 番目の後にput():

[u'114b', u'drottninggatan', u'norrmalm', u'stockholm', u'stockholm', u'stockholms lan', u'sverige']
4

3 に答える 3

2

本当の問題は、周囲のへの呼び出しに対してGAE が を呼び出す順序にある_prepare_for_put()​​ようです。StructuredProperty_pre_put_hook()Model

に書いていaddress_componentsましたItem._pre_put_hook()。onを呼び出す前にGAE が の を計算したと仮定ComputedPropertyします。ComputedProperty から読み取ると、その値が再計算されます。StructuredProperty_pre_put_hook()Item

これをの最後に追加しました_pre_put_hook()

# quick-fix: ComputedProperty not getting generated properly
# read from all ComputedProperties, to compute them again before put
_ = self.address_components_ascii

IDE の警告を避けるために、戻り値をダミー変数に保存しています。

于 2015-05-17T11:19:16.827 に答える
1

このコードを開発サーバーで試したところ、うまくいきました。計算されたプロパティは、配置の前後にアクセスできます。

from google.appengine.ext import ndb

class TestLocation(ndb.Model):
  address = ndb.StringProperty(repeated=True)
  address_ascii = ndb.ComputedProperty(lambda self: [
    part.lower() for part in self.address], repeated=True)

class TestItem(ndb.Model):
  location = ndb.StructuredProperty(TestLocation)

item = TestItem(id='test', location=TestLocation(
  address=['Drottninggatan', 'Norrmalm']))
assert item.location.address_ascii == ['drottninggatan', 'norrmalm']
item.put()
assert TestItem.get_by_id('test').location.address_ascii == [
  'drottninggatan', 'norrmalm']
于 2015-05-17T06:37:50.247 に答える
0

これは の制限のようndbです。put()a に続けて aget()と別のものを実行するだけでうまくいきput()ました。遅くなりますが、初めてオブジェクトを作成するときにのみ必要です。

このメソッドを追加しました:

def double_put(self):
        return self.put().get().put()

これは のドロップイン代替品ですput()

put()新しいオブジェクトを呼び出すときは、 のMyObject.double_put()代わりにMyObject.put().

于 2015-05-15T23:07:37.610 に答える