def _update_many(cls, documents: List[dict]) -> (List[dict], List[dict]): previous_documents = [] new_documents = [] revision = cls._increment(*REVISION_COUNTER) for document in documents: document_keys = cls._to_primary_keys_model(document) document_keys[cls.valid_until_revision.name] = -1 previous_document = cls.__collection__.find_one( document_keys, projection={"_id": False}) if not previous_document: raise ModelCouldNotBeFound(document_keys) # Set previous version as expired (insert previous as expired) cls.__collection__.insert_one({ **previous_document, cls.valid_until_revision.name: revision }) # Update valid version (update previous) document[cls.valid_since_revision.name] = revision document[cls.valid_until_revision.name] = -1 new_document = cls.__collection__.find_one_and_update( document_keys, {"$set": document}, return_document=pymongo.ReturnDocument.AFTER, ) previous_documents.append(previous_document) new_documents.append(new_document) if cls.audit_model: cls.audit_model.audit_update(revision) return previous_documents, new_documents
def _update_one(cls, document: dict) -> (dict, dict): document_keys = cls._to_primary_keys_model(document) previous_document = cls.__collection__.find_one(document_keys) if not previous_document: raise ModelCouldNotBeFound(document_keys) new_document = cls.__collection__.find_one_and_update( document_keys, {"$set": document}, return_document=pymongo.ReturnDocument.AFTER, ) if cls.audit_model: cls.audit_model.audit_update(new_document) return previous_document, new_document
def update_all(cls, rows: List[dict]) -> (List[dict], List[dict]): """ Update models formatted as a list of dictionaries. :raises ValidationFailed in case Marshmallow validation fail. :returns A tuple containing previous models formatted as a list of dictionaries (first item) and new models formatted as a list of dictionaries (second item). """ if not rows: raise ValidationFailed({}, message="No data provided.") previous_rows = [] new_rows = [] new_models = [] for row in rows: if not isinstance(row, dict): raise ValidationFailed(row, message="Must be a dictionary.") try: previous_model = cls.schema().get_instance(row) except exc.sa_exc.DBAPIError: cls._handle_connection_failure() if not previous_model: raise ModelCouldNotBeFound(row) previous_row = _model_field_values(previous_model) try: new_model = cls.schema().load(row, instance=previous_model, partial=True, session=cls._session) except ValidationError as e: raise ValidationFailed(row, e.messages) new_row = _model_field_values(new_model) previous_rows.append(previous_row) new_rows.append(new_row) new_models.append(new_model) try: cls._session.add_all(new_models) if cls.audit_model: for new_row in new_rows: cls.audit_model.audit_update(new_row) cls._session.commit() return previous_rows, new_rows except exc.sa_exc.DBAPIError: cls._session.rollback() cls._handle_connection_failure() except Exception: cls._session.rollback() raise
def _update_many(cls, documents: List[dict]) -> (List[dict], List[dict]): previous_documents = [] new_documents = [] for document in documents: document_keys = cls._to_primary_keys_model(document) previous_document = cls.__collection__.find_one(document_keys) if not previous_document: raise ModelCouldNotBeFound(document_keys) new_document = cls.__collection__.find_one_and_update( document_keys, {"$set": document}, return_document=pymongo.ReturnDocument.AFTER, ) previous_documents.append(previous_document) new_documents.append(new_document) if cls.audit_model: cls.audit_model.audit_update(new_document) return previous_documents, new_documents