1

多数の既存のインスタンスを持つエンティティ モデルにリスト プロパティを追加しました。

class MyModel(db.Model):

    new_property = db.ListProperty(item_type=str, default=None)

ライブ環境にデプロイすると、アプリは短時間問題なく実行されますが、データストアからレコードを取得しようとすると、BadValueError エラーがスローされ始めます。

エラーをスローするコードは、データストアへの単純な呼び出しです。

app_item = db.get(app_item_key)

私は1.7.5を使用しています。Python 2.7 ランタイムの。

これを防ぐためにできること、または少なくともトラップしてストアからデータを取得できるようにするためのアイデアはありますか?

Traceback (most recent call last):
  File "/base/data/home/apps/app/4-15.365909351579418812/app.py", line 1739, in app_get
    app_item = db.get(app_item_key)
  File "/python27_runtime/python27_lib/versions/1/google/appengine/ext/db/__init__.py", line 1533, in get
    return get_async(keys, **kwargs).get_result()
  File "/python27_runtime/python27_lib/versions/1/google/appengine/api/apiproxy_stub_map.py", line 604, in get_result
    return self.__get_result_hook(self)
  File "/python27_runtime/python27_lib/versions/1/google/appengine/datastore/datastore_rpc.py", line 1459, in __get_hook
    entities = rpc.user_data(entities)
  File "/python27_runtime/python27_lib/versions/1/google/appengine/api/datastore.py", line 600, in local_extra_hook
    return extra_hook(result)
  File "/python27_runtime/python27_lib/versions/1/google/appengine/ext/db/__init__.py", line 1503, in extra_hook
    model = cls1.from_entity(entity)
  File "/python27_runtime/python27_lib/versions/1/google/appengine/ext/db/__init__.py", line 1438, in from_entity
    return cls(None, _from_entity=entity, **entity_values)
  File "/python27_runtime/python27_lib/versions/1/google/appengine/ext/db/__init__.py", line 970, in __init__
    prop.__set__(self, value)
  File "/python27_runtime/python27_lib/versions/1/google/appengine/ext/db/__init__.py", line 614, in __set__
    value = self.validate(value)
  File "/python27_runtime/python27_lib/versions/1/google/appengine/ext/db/__init__.py", line 3460, in validate
    value = super(ListProperty, self).validate(value)
  File "/python27_runtime/python27_lib/versions/1/google/appengine/ext/db/__init__.py", line 641, in validate
    raise BadValueError('Property %s is required' % self.name)
BadValueError: Property new_property is required

次の場合:

Aaron D の提案に従って、デフォルト値を空のリストに変更すると、この問題が解決したため、次のようになります。

new_property = db.ListProperty(item_type=str, default=None)

読むべき:

new_property = db.ListProperty(item_type=str, default=[])
4

2 に答える 2

1

トレースバックで参照されているGoogleAppEngineのソースコードを見ると__init__.py、ListPropertyドキュメントのコメント(3428行目)に次のようなコメントがあります。

'required'の唯一の許容値はTrueであることに注意してください。

したがって、提供していなくても、3442行目で自動的に設定されているように見えます。 self._require_parameter(kwds, 'required', True)

ソースコード(3500行目)をさらに調べるempty()と、ListProperty:の定義がわかります。

def empty(self, value):
    """Is list property empty.

    [] is not an empty value.

    Returns:
      True if value is None, else false.
    """
    return value is None

エラーの原因となる可能性のある2つの問題が考えられますが、テストでは検証していません。

1)何らかの理由で、そのフィールドにすでにデータがあり(おそらくnew_property名前を再利用していますか?)、それが空の場合は、エラーが発生する可能性があります。代わりに一意の名前を使用することを提案する場合を除いて、この問題を修正する方法がわかりませんnew_propertyコメントで参照した投稿では、データを「修正」する方法について説明しています。

2)すでにレコードがあるため、コードはデフォルト値のを使用してレコードにデータを入力しようとしています。これはテストNoneに一致しempty()、例外をスローします。その場合、[]代わりにデフォルト値を指定するだけで機能するはずです。

于 2013-03-13T03:34:39.030 に答える
0

ここでのコード例は、あなたが使用しているものではないと確信しています。私はあなたがrequired=True新しい財産にいるに違いない. 次に、必要なプロパティの値を持たない古いレコードを取得しています。「required=True」をドロップするだけで、これらのエラーはなくなります。その値を必須にする必要がある場合は、制約を適用する前にフィールドにデフォルト値を追加する必要があります。

None* ListProperty の有効なデフォルト値ではないというゴミを完全に削除しました *

それで、あなたが提供した情報に基づいて状況を再現しようとしましたが、答えがあります. new_propertyこの問題を生成するには、最初に StringProperty 型の名前を持つモデルを作成し、デフォルトを None にします。ListProperty`の値のないレコードを put() し、レコードをnew_property getting the default of None written, then change the model definition of new_property toフェッチします。同じスタック トレースが得られます。以下のシェルログを参照してください。

s~lightning-catfish> class MyModel(db.Model):
...   pass
... 
s~lightning-catfish> x = MyModel()
s~lightning-catfish> x.put()
datastore_types.Key.from_path(u'MyModel', 1001L, _app=u's~lightning-catfish')
s~lightning-catfish> class MyModel(db.Model):
...    new_property = db.ListProperty(item_type=str,default=None)
... 
s~lightning-catfish> y = db.get(x.key())
s~lightning-catfish> y
<MyModel object at 0x9e09dcc>
s~lightning-catfish> y.new_property
[]
s~lightning-catfish>    new_property = db.StringProperty(defaul
KeyboardInterrupt
s~lightning-catfish> class MyModel(db.Model):
...    new_property = db.StringProperty(default=None)
... 
s~lightning-catfish> z = MyModel()
s~lightning-catfish> z.put()
datastore_types.Key.from_path(u'MyModel', 2001L, _app=u's~lightning-catfish')
s~lightning-catfish> class MyModel(db.Model):
...    new_property = db.ListProperty(item_type=str,default=None)
... 
s~lightning-catfish> a1 = db.get(z.key())
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/home/timh/google_appengine/google/appengine/ext/db/__init__.py", line 1533, in get
    return get_async(keys, **kwargs).get_result()
  File "/home/timh/google_appengine/google/appengine/api/apiproxy_stub_map.py", line 604, in get_result
    return self.__get_result_hook(self)
  File "/home/timh/google_appengine/google/appengine/datastore/datastore_rpc.py", line 1459, in __get_hook
    entities = rpc.user_data(entities)
  File "/home/timh/google_appengine/google/appengine/api/datastore.py", line 600, in local_extra_hook
    return extra_hook(result)
  File "/home/timh/google_appengine/google/appengine/ext/db/__init__.py", line 1503, in extra_hook
    model = cls1.from_entity(entity)
  File "/home/timh/google_appengine/google/appengine/ext/db/__init__.py", line 1438, in from_entity
    return cls(None, _from_entity=entity, **entity_values)
  File "/home/timh/google_appengine/google/appengine/ext/db/__init__.py", line 970, in __init__
    prop.__set__(self, value)
  File "/home/timh/google_appengine/google/appengine/ext/db/__init__.py", line 614, in __set__
    value = self.validate(value)
  File "/home/timh/google_appengine/google/appengine/ext/db/__init__.py", line 3460, in validate
    value = super(ListProperty, self).validate(value)
  File "/home/timh/google_appengine/google/appengine/ext/db/__init__.py", line 641, in validate
    raise BadValueError('Property %s is required' % self.name)
BadValueError: Property new_property is required
s~lightning-catfish> 

データを修正するには、低レベルでアクセスして、レコードに格納されているデータ型を変更する必要があります。

必要に応じて、モデルを使用せずにエンティティをフェッチして配置するためのコードがあります。

* 最後に試すべきこと *

次のコードなどを使用して、モデルを使用せずにオブジェクトをフェッチしてみてください。タイプなどを使用して、基礎となるデータを取得します。辞書で。これにより、データストアの内容が表示されます。

from google.appengine.api import datastore
from google.appengine.api import datastore_errors

def get_entities(keys):
    rpc = datastore.GetRpcFromKwargs({})
    keys, multiple = datastore.NormalizeAndTypeCheckKeys(keys)
    entities = None
    try:
        entities = datastore.Get(keys, rpc=rpc)
    except datastore_errors.EntityNotFoundError:
        assert not multiple

    return entities


x = get_entities([some_key])
于 2013-03-12T23:16:46.817 に答える