mapreduce を使用して GAE のデータストアでスキーマのアップグレードを実行するための基盤のセットアップが完了しました。NDB を使用しており、モデルの多くまたはモデルは、DateTimeProperty の auto_now キーワード オプションを使用して、last_modified 属性を設定します。
last_modified = ndb.DateTimeProperty( auto_now=True )
もちろん、エンティティを更新する mapreduce ジョブを実行すると、last_modified 属性も更新されますが、これは実際には望んでいないことです。
def upgrade_entity(entity):
# modify entity
yield op.db.Put(entity)
ドキュメントによると、auto_now_add を設定してプロパティの値をオーバーライドできますが、auto_now ではオーバーライドできません。
last_modified 属性も更新したくない状況が他にもあるのではないかと考えています。
それで、エンティティの last_modified 値を保持する方法はありますか、それとも別のプロパティを追加するか、これらのプロパティを制御できるものに置き換えて、値を手動で設定するだけですか?
わかりましたので、コンセンサスは、ユーザー向けのコードではなく、mapreduce コードでのみ使用されるモデルの代替バージョンを定義できるはずだということです (サイトをシャットダウンして実行する必要は避けたいと思っています)。スキーマのアップグレード) しかし、これを機能させることができませんでした。
次のセットアップでは、適切に動作する (last_modified を更新しない) mapreduce を実行するまで、ユーザー向けのコードは適切に動作します (last_modifed を更新します)。mapreduce を実行した後、ユーザー向けコードは last_modified を更新しなくなりました。
models.py
class MyModel(ndb.Model):
# model used by user facing code
last_modified = ndb.DateTimeProperty( auto_now=True )
upgrade.py
class MyTmpModel(ndb.Model):
# model used by mapreduce code
@classmethod
def _get_kind(cls):
return 'MyModel'
last_modified = ndb.DateTimeProperty( auto_now=False )
def upgrade_model(entity):
# mapper function
# modify entity
yield op.db.Put(entity)
mapreduce.yaml
mapreduce:
- name: Upgrade Model
mapper:
input_reader: mapreduce.input_readers.DatastoreInputReader
handler: upgrade.upgrade_model
params:
- name: entity_kind
default: upgrade.MyTmpModel
わかりました、ここで私の問題を dev_server でテストしたという事実と、実際の gae サーバーと比較してそこで実行される方法の違いを説明します。私は、dev_server ではすべてのコードが同じプロセスで実行されており、異なるモデル バージョンがうまく機能していないと結論付けました。NDB モデル ドキュメントから:
アプリケーションは、異なるモジュールに存在する場合でも、同じ種類の 2 つのモデル クラスを定義するべきではありません。アプリケーションの種類は、グローバルな「名前空間」と見なされます。
実際のgaeサーバーではmapreduceコードが別々のインスタンスで実行され、これらのバージョンの衝突は発生せず、サーバーインスタンスに直面しているユーザーには影響しないため、上記のセットアップは期待どおりに機能するという事実に頼ることができると仮定します. .
助けてくれたティムとグイドに感謝します。
乾杯、
J