Ejemplo n.º 1
0
    def store(self, with_transaction=True):
        """
        Store a new node in the DB, also saving its repository directory
        and attributes.

        After being called attributes cannot be
        changed anymore! Instead, extras can be changed only AFTER calling
        this store() function.

        :note: After successful storage, those links that are in the cache, and
            for which also the parent node is already stored, will be
            automatically stored. The others will remain unstored.

        :parameter with_transaction: if False, no transaction is used. This
          is meant to be used ONLY if the outer calling function has already
          a transaction open!
        """
        from aiida.backends.sqlalchemy import get_scoped_session
        session = get_scoped_session()

        # TODO: This needs to be generalized, allowing for flexible methods
        # for storing data and its attributes.
        if self._to_be_stored:
            self._validate()

            self._check_are_parents_stored()

            # I save the corresponding django entry
            # I set the folder
            # NOTE: I first store the files, then only if this is successful,
            # I store the DB entry. In this way,
            # I assume that if a node exists in the DB, its folder is in place.
            # On the other hand, periodically the user might need to run some
            # bookkeeping utility to check for lone folders.
            self._repository_folder.replace_with_folder(
                self._get_temp_folder().abspath, move=True, overwrite=True)

            #    import aiida.backends.sqlalchemy
            try:
                # aiida.backends.sqlalchemy.get_scoped_session().add(self._dbnode)
                session.add(self._dbnode)
                # Save its attributes 'manually' without incrementing
                # the version for each add.
                self.dbnode.attributes = self._attrs_cache
                flag_modified(self.dbnode, "attributes")
                # This should not be used anymore: I delete it to
                # possibly free memory
                del self._attrs_cache

                self._temp_folder = None
                self._to_be_stored = False

                # Here, I store those links that were in the cache and
                # that are between stored nodes.
                self._store_cached_input_links(with_transaction=False)

                if with_transaction:
                    try:
                        # aiida.backends.sqlalchemy.get_scoped_session().commit()
                        session.commit()
                    except SQLAlchemyError as e:
                        #print "Cannot store the node. Original exception: {" \
                        #      "}".format(e)
                        session.rollback()
                        raise

            # This is one of the few cases where it is ok to do a 'global'
            # except, also because I am re-raising the exception
            except:
                # I put back the files in the sandbox folder since the
                # transaction did not succeed
                self._get_temp_folder().replace_with_folder(
                    self._repository_folder.abspath, move=True, overwrite=True)
                raise

            # Set up autogrouping used be verdi run
            autogroup = aiida.orm.autogroup.current_autogroup
            grouptype = aiida.orm.autogroup.VERDIAUTOGROUP_TYPE

            if autogroup is not None:
                if not isinstance(autogroup, aiida.orm.autogroup.Autogroup):
                    raise ValidationError(
                        "current_autogroup is not an AiiDA Autogroup")

                if autogroup.is_to_be_grouped(self):
                    group_name = autogroup.get_group_name()
                    if group_name is not None:
                        g = Group.get_or_create(name=group_name,
                                                type_string=grouptype)[0]
                        g.add_nodes(self)

        return self
Ejemplo n.º 2
0
 def get_aiida_class(self):
     from aiida.orm.implementation.sqlalchemy.group import Group
     return Group(dbgroup=self)