3

GAEデータストアがプロパティタイプをStringPropertyからTextProperty(モデル定義を事実上無視する)に変更する可能性がある状況はありますか?

次の状況を考慮してください(簡略化)。

class MyModel(db.Model):
    user_input = db.StringProperty(default='', multiline=True)

私のデータストア内のこのモデルの一部のエンティティインスタンスは、TextProperty(単純ではなく)'user_input'のデータ型を持ってstrいるため、インデックスが作成されません。これを修正するには、エンティティを取得し、設定model_instance.user_input = str(model_instance.user_input)してから、エンティティをデータストアに戻します。

私が理解していないのは、このモデルに変更がない場合に、これが一部のエンティティにのみどのように発生するかです。db.modelのプロパティの「type」をからStringPropertyにオーバーライドできる可能性はありTextPropertyますか?

4

4 に答える 4

1

少なくとも、プロパティにインデックスが付けられていない場合は、ndb Unicodeを含むStringPropertiesの特別なコードパス があります。この場合、テキストプロパティに変更されます。関連するスニペットは次のとおりです。

if isinstance(value, str):
  v.set_stringvalue(value)
elif isinstance(value, unicode):
  v.set_stringvalue(value.encode('utf8'))
  if not self._indexed:
    p.set_meaning(entity_pb.Property.TEXT)

Python側でこれを観察することはできませんが(db.StringPropertyを参照してくださいが、プロパティはdatastore_types.Text?である場合があります)、データストアに表示され、データストアをBigQueryに読み込むときに問題が発生しました。

したがって、使用するのは次のとおりです。

  • StringProperty(indexed = True)
  • TextProperty()

外部データで発生する傾向があるため、プロパティに混合値と値をStringProperty(indexed=False)書き込む可能性がある場合は避けてください。unicodestr

于 2018-12-13T14:35:43.917 に答える
0

StringProperty500文字の長さ制限があります。確かなことはわかりませんが、データストアが制限を超えると、をに変換する可能性がありStringPropertyますTextProperty

そうは言っても、GAEがインデックス付きのプロパティをインデックスなしのプロパティに暗黙的に変更するだけではないかと思います。しかし、私が考えることができるのはそれだけです。

于 2013-03-06T18:13:13.633 に答える
0

モデルの定義からのプロパティのタイプをバイパスできる方法があることがわかりました(これは私たちの場合でした)!次の自己完結型の例は、インタラクティブコンソールで実行され、バグを示しています。基本的にsetattr、別のタイプの既存のプロパティを割り当てる場合、プロパティのタイプをバイパスします。

from google.appengine.ext import db
class TestModel(db.Model):
    string_type = db.StringProperty(default='', multiline=True)
    text_type = db.TextProperty()

some_instance = TestModel()
some_instance.text_type = 'foobar'
setattr(some_instance, 'string_type', some_instance.text_type)
some_instance.put()

retrieved_instance = db.get(some_instance.key())

print id(retrieved_instance.string_type) #10166414447674124776
print id(retrieved_instance.text_type) #10166414447721032360

print type(retrieved_instance.string_type) #OOPS: string_type is now Text type!
于 2013-03-07T11:16:45.993 に答える
0

setattrsetattr(some_instance, 'string_type', some_instance.text_type)を使用すると、string_typeプロパティという名前のインスタンスプロパティが実際にtext_typeプロパティを指すようになります。したがって、2つの名前が1つのプロパティになります

The db, ndb, users, urlfetch, and memcache modules are imported.
> from google.appengine.ext import db
> class TestModel(db.Model):
...    string_type = db.StringProperty(default='', multiline=True)
...    text_type = db.TextProperty()
... 
> 
> some_instance = TestModel()
> some_instance.text_type = 'foobar'
> setattr(some_instance, 'string_type', some_instance.text_type)
> print type(some_instance.string_type)
<class 'google.appengine.api.datastore_types.Text'>
y> repr(some_instance.string_type)
"u'foobar'"
> id(some_instance.string_type)
168217452
> id(some_instance.text_type)
168217452
> some_instance.string_type.__class__
<class 'google.appengine.api.datastore_types.Text'>
> some_instance.text_type.__class__
<class 'google.appengine.api.datastore_types.Text'>
> dir(some_instance.text_type.__class__)

上記の2つのプロパティのIDに注意してください。

したがって、インスタンスレベルのプロパティ定義を効果的に再バインドすると、この変更されたモデルがフィールドのタイプでデータストアに書き込まれます。

setattrを使用する場合(この不自然な例では理由がわかりませんが)setattr(some_instance.string_type,TestModel.string_type.get_value_for_datastore(some_instance) )、インスタンスプロパティを再バインドするのではなく、割り当てられる値を取得するために最初にを使用してプロパティから値を取得する必要があります。

于 2013-03-08T00:00:10.803 に答える