Python sqlalchemy.orm.collections.InstrumentedList() Examples

The following are 7 code examples of sqlalchemy.orm.collections.InstrumentedList(). You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may also want to check out all available functions/classes of the module sqlalchemy.orm.collections , or try the search function .
Example #1
Source File: base.py    From cloud-inquisitor with Apache License 2.0 5 votes vote down vote up
def to_json(self):
        """Exports the object to a JSON friendly dict

        Returns:
             Dict representation of object type
        """
        output = {
            '__type': self.__class__.__name__
        }

        cls_attribs = self.__class__.__dict__
        for attrName in cls_attribs:
            attr = getattr(self.__class__, attrName)
            value = getattr(self, attrName)
            value_class = type(value)

            if issubclass(type(attr), QueryableAttribute):
                # List of Model, BaseModelMixin objects (one-to-many relationship)
                if issubclass(value_class, InstrumentedList):
                    output[to_camelcase(attrName)] = [x.to_json() for x in value]

                # Model, BaseModelMixin object (one-to-one relationship)
                elif issubclass(value_class, Model):
                    output[to_camelcase(attrName)] = value.to_json()

                # Datetime object
                elif isinstance(value, datetime):
                    output[to_camelcase(attrName)] = isoformat(value)

                elif isinstance(value, enum.Enum):
                    output[to_camelcase(attrName)] = value.name

                # Any primitive type
                else:
                    output[to_camelcase(attrName)] = value

        return output 
Example #2
Source File: test_models.py    From octavia with Apache License 2.0 5 votes vote down vote up
def count_graph_nodes(self, node, _graph_nodes=None):
        """Counts connected BaseDataModel nodes in a graph given the

        starting node. Node should be a data model in any case.
        """
        _graph_nodes = _graph_nodes or []
        total = 0
        mykey = self._get_unique_key(node)
        if mykey in _graph_nodes:
            # Seen this node already
            return total
        else:
            total += 1
            _graph_nodes.append(mykey)
            attr_names = [attr_name for attr_name in dir(node)
                          if not attr_name.startswith('_')]
            for attr_name in attr_names:
                attr = getattr(node, attr_name)
                if isinstance(attr, data_models.BaseDataModel):
                    total += self.count_graph_nodes(
                        attr, _graph_nodes=_graph_nodes)
                elif isinstance(attr, (collections.InstrumentedList, list)):
                    for item in attr:
                        if isinstance(item, data_models.BaseDataModel):
                            total += self.count_graph_nodes(
                                item, _graph_nodes=_graph_nodes)
        return total 
Example #3
Source File: data_models.py    From octavia with Apache License 2.0 5 votes vote down vote up
def _find_in_graph(self, key, _visited_nodes=None):
        """Locates an object with the given unique key in the current

        object graph and returns a reference to it.
        """
        _visited_nodes = _visited_nodes or []
        mykey = self._get_unique_key()
        if mykey in _visited_nodes:
            # Seen this node already, don't traverse further
            return None
        if mykey == key:
            return self
        _visited_nodes.append(mykey)
        attr_names = [attr_name for attr_name in dir(self)
                      if not attr_name.startswith('_')]
        for attr_name in attr_names:
            attr = getattr(self, attr_name)
            if isinstance(attr, BaseDataModel):
                result = attr._find_in_graph(
                    key, _visited_nodes=_visited_nodes)
                if result is not None:
                    return result
            elif isinstance(attr, (collections.InstrumentedList, list)):
                for item in attr:
                    if isinstance(item, BaseDataModel):
                        result = item._find_in_graph(
                            key, _visited_nodes=_visited_nodes)
                        if result is not None:
                            return result
        # If we are here we didn't find it.
        return None 
Example #4
Source File: schema.py    From lemur with Apache License 2.0 5 votes vote down vote up
def unwrap_envelope(self, data, many):
        if many:
            if data["items"]:
                if isinstance(data, InstrumentedList) or isinstance(data, list):
                    self.context["total"] = len(data)
                    return data
                else:
                    self.context["total"] = data["total"]
            else:
                self.context["total"] = 0
                data = {"items": []}

            return data["items"]

        return data 
Example #5
Source File: alchemy.py    From flask-rest-jsonapi with MIT License 5 votes vote down vote up
def get_relationship(self, relationship_field, related_type_, related_id_field, view_kwargs):
        """Get a relationship

        :param str relationship_field: the model attribute used for relationship
        :param str related_type_: the related resource type
        :param str related_id_field: the identifier field of the related model
        :param dict view_kwargs: kwargs from the resource view
        :return tuple: the object and related object(s)
        """
        self.before_get_relationship(relationship_field, related_type_, related_id_field, view_kwargs)

        obj = self.get_object(view_kwargs)

        if obj is None:
            url_field = getattr(self, 'url_field', 'id')
            filter_value = view_kwargs[url_field]
            raise ObjectNotFound('{}: {} not found'.format(self.model.__name__, filter_value),
                                 source={'parameter': url_field})

        if not hasattr(obj, relationship_field):
            raise RelationNotFound("{} has no attribute {}".format(obj.__class__.__name__, relationship_field))

        related_objects = getattr(obj, relationship_field)

        if related_objects is None:
            return obj, related_objects

        self.after_get_relationship(obj, related_objects, relationship_field, related_type_, related_id_field,
                                    view_kwargs)

        if isinstance(related_objects, InstrumentedList):
            return obj,\
                [{'type': related_type_, 'id': getattr(obj_, related_id_field)} for obj_ in related_objects]
        else:
            return obj, {'type': related_type_, 'id': getattr(related_objects, related_id_field)} 
Example #6
Source File: base_models.py    From octavia with Apache License 2.0 4 votes vote down vote up
def to_data_model(self, _graph_nodes=None):
        """Converts to a data model graph.

        In order to make the resulting data model graph usable no matter how
        many internal references are followed, we generate a complete graph of
        OctaviaBase nodes connected to the object passed to this method.

        :param _graph_nodes: Used only for internal recursion of this
                             method. Should not be called from the outside.
                             Contains a dictionary of all OctaviaBase type
                             objects in the generated graph
        """
        _graph_nodes = _graph_nodes or {}
        if not self.__data_model__:
            raise NotImplementedError
        dm_kwargs = {}
        for column in self.__table__.columns:
            dm_kwargs[column.name] = getattr(self, column.name)

        attr_names = [attr_name for attr_name in dir(self)
                      if not attr_name.startswith('_')]
        # Appending early, as any unique ID should be defined already and
        # the rest of this object will get filled out more fully later on,
        # and we need to add ourselves to the _graph_nodes before we
        # attempt recursion.
        dm_self = self.__data_model__(**dm_kwargs)
        dm_key = self._get_unique_key(dm_self)
        _graph_nodes.update({dm_key: dm_self})
        for attr_name in attr_names:
            attr = getattr(self, attr_name)
            if isinstance(attr, OctaviaBase) and attr.__class__:
                # If this attr is already in the graph node list, just
                # reference it there and don't recurse.
                ukey = self._get_unique_key(attr)
                if ukey in _graph_nodes.keys():
                    setattr(dm_self, attr_name, _graph_nodes[ukey])
                else:
                    setattr(dm_self, attr_name, attr.to_data_model(
                        _graph_nodes=_graph_nodes))
            elif isinstance(attr, (collections.InstrumentedList, list)):
                setattr(dm_self, attr_name, [])
                listref = getattr(dm_self, attr_name)
                for item in attr:
                    if isinstance(item, OctaviaBase) and item.__class__:
                        ukey = self._get_unique_key(item)
                        if ukey in _graph_nodes.keys():
                            listref.append(_graph_nodes[ukey])
                        else:
                            listref.append(
                                item.to_data_model(_graph_nodes=_graph_nodes))
                    elif not isinstance(item, OctaviaBase):
                        listref.append(item)
        return dm_self 
Example #7
Source File: database.py    From eNMS with GNU General Public License v3.0 4 votes vote down vote up
def configure_application_events(self, app):
        @event.listens_for(self.base, "after_insert", propagate=True)
        def log_instance_creation(mapper, connection, target):
            if hasattr(target, "name"):
                app.log("info", f"CREATION: {target.type} '{target.name}'")

        @event.listens_for(self.base, "before_delete", propagate=True)
        def log_instance_deletion(mapper, connection, target):
            name = getattr(target, "name", str(target))
            app.log("info", f"DELETION: {target.type} '{name}'")

        @event.listens_for(self.base, "before_update", propagate=True)
        def log_instance_update(mapper, connection, target):
            state, changelog = inspect(target), []
            for attr in state.attrs:
                hist = state.get_history(attr.key, True)
                if (
                    getattr(target, "private", False)
                    or not getattr(target, "log_changes", True)
                    or not getattr(state.class_, attr.key).info.get("log_change", True)
                    or attr.key in self.private_properties
                    or not hist.has_changes()
                ):
                    continue
                change = f"{attr.key}: "
                property_type = type(getattr(target, attr.key))
                if property_type in (InstrumentedList, MutableList):
                    if property_type == MutableList:
                        added = [x for x in hist.added[0] if x not in hist.deleted[0]]
                        deleted = [x for x in hist.deleted[0] if x not in hist.added[0]]
                    else:
                        added, deleted = hist.added, hist.deleted
                    if deleted:
                        change += f"DELETED: {deleted}"
                    if added:
                        change += f"{' / ' if deleted else ''}ADDED: {added}"
                else:
                    change += (
                        f"'{hist.deleted[0] if hist.deleted else None}' => "
                        f"'{hist.added[0] if hist.added else None}'"
                    )
                changelog.append(change)
            if changelog:
                name, changes = (
                    getattr(target, "name", target.id),
                    " | ".join(changelog),
                )
                app.log("info", f"UPDATE: {target.type} '{name}': ({changes})")

        if app.use_vault:

            @event.listens_for(models["service"].name, "set", propagate=True)
            def vault_update(target, new_value, old_value, *_):
                path = f"secret/data/{target.type}/{old_value}/password"
                data = app.vault_client.read(path)
                if not data:
                    return
                app.vault_client.write(
                    f"secret/data/{target.type}/{new_value}/password",
                    data={"password": data["data"]["data"]["password"]},
                )