def _update_skill( skill_model: skill_models.SkillModel, migrated_skill: skill_domain.Skill, skill_changes: Sequence[skill_domain.SkillChange] ) -> Sequence[base_models.BaseModel]: """Generates newly updated skill models. Args: skill_model: SkillModel. The skill which should be updated. migrated_skill: Skill. The migrated skill domain object. skill_changes: sequence(SkillChange). The skill changes to apply. Returns: sequence(BaseModel). Sequence of models which should be put into the datastore. """ updated_skill_model = (skill_services.populate_skill_model_fields( skill_model, migrated_skill)) commit_message = ('Update skill content schema version to %d and ' 'skill misconceptions schema version to %d and ' 'skill rubrics schema version to %d.') % ( feconf.CURRENT_SKILL_CONTENTS_SCHEMA_VERSION, feconf.CURRENT_MISCONCEPTIONS_SCHEMA_VERSION, feconf.CURRENT_RUBRIC_SCHEMA_VERSION) change_dicts = [change.to_dict() for change in skill_changes] with datastore_services.get_ndb_context(): models_to_put = updated_skill_model.compute_models_to_commit( feconf.MIGRATION_BOT_USERNAME, feconf.COMMIT_TYPE_EDIT, commit_message, change_dicts, additional_models={}).values() datastore_services.update_timestamps_multi(list(models_to_put)) return models_to_put
def _update_story( story_model: story_models.StoryModel, migrated_story: story_domain.Story, story_change: story_domain.StoryChange ) -> Sequence[base_models.BaseModel]: """Generates newly updated story models. Args: story_model: StoryModel. The story which should be updated. migrated_story: Story. The migrated story domain object. story_change: StoryChange. The story change to apply. Returns: sequence(BaseModel). Sequence of models which should be put into the datastore. """ updated_story_model = story_services.populate_story_model_fields( story_model, migrated_story) change_dicts = [story_change.to_dict()] with datastore_services.get_ndb_context(): models_to_put = updated_story_model.compute_models_to_commit( feconf.MIGRATION_BOT_USERNAME, feconf.COMMIT_TYPE_EDIT, 'Update story contents schema version to %d.' % ( feconf.CURRENT_STORY_CONTENTS_SCHEMA_VERSION), change_dicts, additional_models={} ) models_to_put_values = [] for _, value in models_to_put.items(): # Here, we are narrowing down the type from object to BaseModel. assert isinstance(value, base_models.BaseModel) models_to_put_values.append(value) datastore_services.update_timestamps_multi(models_to_put_values) return models_to_put_values
def setUp(self): super().setUp() story_summary_model = self.create_model( story_models.StorySummaryModel, id=self.STORY_1_ID, title='title', url_fragment='urlfragment', language_code='cs', description='description', node_titles=['title1', 'title2'], story_model_last_updated=datetime.datetime.utcnow(), story_model_created_on=datetime.datetime.utcnow(), version=1) topic_model = self.create_model( topic_models.TopicModel, id=self.TOPIC_1_ID, name='topic title', canonical_name='topic title', story_reference_schema_version=1, subtopic_schema_version=1, next_subtopic_id=1, language_code='cs', url_fragment='topic', canonical_story_references=[{ 'story_id': self.STORY_1_ID, 'story_is_published': False }], page_title_fragment_for_web='fragm', ) datastore_services.update_timestamps_multi( [topic_model, story_summary_model]) datastore_services.put_multi([topic_model, story_summary_model]) self.latest_contents = { 'nodes': [{ 'id': 'node_1111', 'title': 'title', 'description': 'description', 'thumbnail_filename': 'thumbnail_filename.svg', 'thumbnail_bg_color': '#F8BF74', 'thumbnail_size_in_bytes': None, 'destination_node_ids': [], 'acquired_skill_ids': [], 'prerequisite_skill_ids': [], 'outline': 'outline', 'outline_is_finalized': True, 'exploration_id': 'exp_id' }], 'initial_node_id': 'node_1111', 'next_node_id': 'node_2222' } self.broken_contents = copy.deepcopy(self.latest_contents) self.broken_contents['nodes'][0]['description'] = 123 self.unmigrated_contents = copy.deepcopy(self.latest_contents) self.unmigrated_contents['nodes'][0]['thumbnail_size_in_bytes'] = 123
def put_multi(self, model_list: Sequence[base_models.BaseModel]) -> None: """Puts the input models into the datastore. Args: model_list: list(Model). The NDB models to put into the datastore. """ datastore_services.update_timestamps_multi( model_list, update_last_updated_time=False) datastore_services.put_multi(model_list)
def mark_outdated_models_as_deleted() -> None: """Mark models in MODEL_CLASSES_TO_MARK_AS_DELETED, as deleted if they were last updated more than four weeks ago. """ date_before_which_to_mark_as_deleted = ( datetime.datetime.utcnow() - feconf.PERIOD_TO_MARK_MODELS_AS_DELETED) models_to_mark_as_deleted: List[base_models.BaseModel] = [] for model_class in MODEL_CLASSES_TO_MARK_AS_DELETED: models_to_mark_as_deleted.extend( model_class.query( model_class.last_updated < date_before_which_to_mark_as_deleted ).fetch()) for model_to_mark_as_deleted in models_to_mark_as_deleted: model_to_mark_as_deleted.deleted = True datastore_services.update_timestamps_multi(models_to_mark_as_deleted) datastore_services.put_multi(models_to_mark_as_deleted)