Exemplo n.º 1
0
    def find_by(self, **kwargs) -> "BaseEntity":
        """Find a specific entity record that matches one or more criteria.

        This method internally uses the `filter` method to fetch records.

        Returns exactly one record that matches the identifier.

        Throws `ObjectNotFoundError` if no record was found for the identifier.
        Throws `TooManyObjectsError` if multiple records were found for the identifier.

        :param kwargs: named arguments of attribute names and values to filter on.
        """
        logger.debug(f"Lookup `{self.entity_cls.__name__}` object with values "
                     f"{kwargs}")

        # Filter for item in the data store
        results = self.query.filter(**kwargs).all()

        if not results:
            raise ObjectNotFoundError({
                "_entity":
                f"`{self.entity_cls.__name__}` object with values {[item for item in kwargs.items()]} "
                f"does not exist."
            })

        if len(results) > 1:
            raise TooManyObjectsError(
                f"More than one object of `{self.entity_cls.__name__}` exist "
                f"with values {[item for item in kwargs.items()]}", )

        # Return the first result, because `filter` would have returned an array
        return results.first
Exemplo n.º 2
0
def test_pickling_of_exceptions():
    exc = ObjectNotFoundError({"_entity": "foo"})

    pickled_exc = pickle.dumps(exc)
    unpickled_exc = pickle.loads(pickled_exc)

    assert exc.messages == unpickled_exc.messages
Exemplo n.º 3
0
    def _update(self, model_obj: Any):
        """Update a model object in the data store and return it"""
        conn = self.provider.get_connection()

        identifier = model_obj.meta.id

        # Fetch the record from database
        try:
            # Calling `get` will raise `NotFoundError` if record was not found
            self.model_cls.get(id=identifier,
                               using=conn,
                               index=self.model_cls._index._name)
        except NotFoundError as exc:
            logger.error(f"Database Record not found: {exc}")
            raise ObjectNotFoundError({
                "_entity":
                f"`{self.entity_cls.__name__}` object with identifier {identifier} "
                f"does not exist."
            })

        try:
            model_obj.save(
                refresh=True,
                index=self.model_cls._index._name,
                using=conn,
            )
        except Exception as exc:
            logger.error(f"Error while creating: {exc}")
            raise

        return model_obj
Exemplo n.º 4
0
    def _update(self, model_obj):
        """Update a record in the sqlalchemy database"""
        conn = self._get_session()
        db_item = None

        # Fetch the record from database
        try:
            identifier = getattr(model_obj,
                                 id_field(self.entity_cls).attribute_name)
            db_item = conn.query(self.model_cls).get(
                identifier
            )  # This will raise exception if object was not found
        except DatabaseError as exc:
            logger.error(f"Database Record not found: {exc}")
            raise

        if db_item is None:
            conn.rollback()
            conn.close()
            raise ObjectNotFoundError({
                "_entity":
                f"`{self.entity_cls.__name__}` object with identifier {identifier} "
                f"does not exist."
            })

        # Sync DB Record with current changes. When the session is committed, changes are automatically synced
        try:
            for attribute in attributes(self.entity_cls):
                if attribute != id_field(
                        self.entity_cls).attribute_name and getattr(
                            model_obj, attribute) != getattr(
                                db_item, attribute):
                    setattr(db_item, attribute, getattr(model_obj, attribute))
        except DatabaseError as exc:
            logger.error(f"Error while updating: {exc}")
            raise
        finally:
            if not current_uow:
                conn.commit()
                conn.close()

        return model_obj
Exemplo n.º 5
0
    def _delete(self, model_obj):
        """Delete the entity record in the dictionary"""
        conn = self._get_session()

        identifier = model_obj[id_field(self.entity_cls).field_name]
        with conn._db["lock"]:
            # Check if object is present
            if identifier not in conn._db["data"][self.schema_name]:
                raise ObjectNotFoundError({
                    "_entity":
                    f"`{self.entity_cls.__name__}` object with identifier {identifier} "
                    f"does not exist."
                })

            del conn._db["data"][self.schema_name][identifier]

        if not current_uow:
            conn.commit()
            conn.close()

        return model_obj
Exemplo n.º 6
0
    def get(self, identifier: Identifier) -> BaseEventSourcedAggregate:
        """Retrieve a fully-formed Aggregate from a stream of Events.

        Args:
            identifier (Identifier): Aggregate identifier

        Raises:
            ObjectNotFoundError: When no stream with identifier is found

        Returns:
            BaseEventSourcedAggregate: The fully-loaded aggregate object
        """
        aggregate = current_domain.event_store.store.load_aggregate(
            self.meta_.aggregate_cls, identifier)

        if not aggregate:
            raise ObjectNotFoundError({
                "_entity":
                f"`{self.meta_.aggregate_cls.__name__}` object with identifier {identifier} "
                f"does not exist."
            })

        return aggregate
Exemplo n.º 7
0
    def get(self, identifier: Any) -> BaseEntity:
        """Retrieve a specific Record from the Repository by its `identifier`.

        This method internally uses the `filter` method to fetch records.

        Returns exactly one record that matches the identifier.

        Throws `ObjectNotFoundError` if no record was found for the identifier.

        Throws `TooManyObjectsError` if multiple records were found for the identifier.

        :param identifier: id of the record to be fetched from the data store.
        """
        logger.debug(
            f"Lookup `{self.entity_cls.__name__}` object with identifier {identifier}"
        )

        # Filter on the ID field of the entity
        filters = {
            id_field(self.entity_cls).field_name: identifier,
        }

        results = self.query.filter(**filters).all()
        if not results:
            raise ObjectNotFoundError({
                "_entity":
                f"`{self.entity_cls.__name__}` object with identifier {identifier} "
                f"does not exist."
            })

        if len(results) > 1:
            raise TooManyObjectsError(
                f"More than one object of `{self.entity_cls.__name__}` exist with identifier {identifier}",
            )

        # Return the first result, because `filter` would have returned an array
        return results.first
Exemplo n.º 8
0
    def _delete(self, model_obj):
        """Delete the entity record in the dictionary"""
        conn = self._get_session()
        db_item = None

        # Fetch the record from database
        try:
            identifier = getattr(model_obj,
                                 id_field(self.entity_cls).attribute_name)
            db_item = conn.query(self.model_cls).get(
                identifier
            )  # This will raise exception if object was not found
        except DatabaseError as exc:
            logger.error(f"Database Record not found: {exc}")
            raise

        if db_item is None:
            conn.rollback()
            conn.close()
            raise ObjectNotFoundError({
                "_entity":
                f"`{self.entity_cls.__name__}` object with identifier {identifier} "
                f"does not exist."
            })

        try:
            conn.delete(db_item)
        except DatabaseError as exc:
            logger.error(f"Error while deleting: {exc}")
            raise
        finally:
            if not current_uow:
                conn.commit()
                conn.close()

        return model_obj