def get_state(self, from_attribute=False): """ Get the state of the calculation. .. note:: this method returns the NOTFOUND state if no state is found in the DB. .. note:: the 'most recent' state is obtained using the logic in the ``aiida.common.datastructures.sort_states`` function. .. todo:: Understand if the state returned when no state entry is found in the DB is the best choice. :param from_attribute: if set to True, read it from the attributes (the attribute is also set with set_state, unless the state is set to IMPORTED; in this way we can also see the state before storing). :return: a string. If from_attribute is True and no attribute is found, return None. If from_attribute is False and no entry is found in the DB, return the "NOTFOUND" state. """ from aiida.backends.djsite.db.models import DbCalcState if from_attribute: return self.get_attr('state', None) else: if not self.is_stored: return calc_states.NEW else: this_calc_states = DbCalcState.objects.filter( dbnode=self).values_list('state', flat=True) if not this_calc_states: return None else: try: most_recent_state = sort_states(this_calc_states)[0] except ValueError as e: raise DbContentError("Error in the content of the " "DbCalcState table ({})".format( e.message)) return most_recent_state
def get_aiida_class(self): """ Return the corresponding aiida instance of class aiida.orm.Node or a appropriate subclass. """ from aiida.common.pluginloader import from_type_to_pluginclassname from aiida.orm.node import Node try: pluginclassname = from_type_to_pluginclassname(self.type) except DbContentError: raise DbContentError("The type name of node with pk= {} is " "not valid: '{}'".format(self.pk, self.type)) try: PluginClass = load_plugin(Node, 'aiida.orm', pluginclassname) except MissingPluginError: aiidalogger.error("Unable to find plugin for type '{}' (node= {}), " "will use base Node class".format(self.type, self.pk)) PluginClass = Node return PluginClass(dbnode=self)
def get_db_columns(db_class): """ This function returns a dictionary where the keys are the columns of the table corresponding to the db_class and the values are the column properties such as type, is_foreign_key and if so, the related table and column. :param db_class: the database model whose schema has to be returned :return: a dictionary """ import datetime django2python_map = { 'AutoField': int, 'BooleanField': bool, 'CharField': str, 'DateTimeField': datetime.datetime, 'EmailField': str, 'FloatField': float, 'IntegerField': int, 'TextField': str, 'UUIDField': str, } ## Retrieve the columns of the table corresponding to the present class columns = db_class._meta.fields column_names = [] column_types = [] column_python_types = [] foreign_keys = [] ## retrieve names, types, and convert types in python types. for column in columns: name = column.get_attname() type = column.get_internal_type() column_names.append(name) # Check for foreignkeys and compile a dictionary with the required # informations if type is 'ForeignKey': # relation is a tuple with the related table and the related field relation = column.resolve_related_fields() if len(relation) == 0: raise DbContentError(' "{}" field has no foreign ' 'relationship') elif len(relation) > 1: raise DbContentError(' "{}" field has not a unique foreign ' 'relationship') else: #Collect infos of the foreing key foreign_keys.append((name, relation[0][0], relation[0][1])) #Change the type according to the type of the related column type = relation[0][1].get_internal_type() column_types.append(type) column_python_types = map(lambda x: django2python_map[x], column_types) ## Fill in the returned dictionary schema = {} # Fill in the keys based on the column names and the types. By default we # assume that columns are no foreign keys for k, v in iter(zip(column_names, column_python_types)): schema[k] = {'type': v, 'is_foreign_key': False} # Add infos about the foreign relationships for k, related_class, related_field in foreign_keys: schema[k].update({ 'is_foreign_key': True, 'related_table': related_class.rel.to.__name__, 'related_column': related_field.get_attname() }) return schema
def getvalue(self, attr): """This can be called on a given row and will get the corresponding value, casting it correctly. """ try: if attr.datatype == 'list' or attr.datatype == 'dict': prefix = '{}{}'.format(attr.key, self._sep) prefix_len = len(prefix) dballsubvalues = self._model_class.objects.filter( key__startswith=prefix, **self.subspecifiers_dict(attr)).values_list( 'key', 'datatype', 'tval', 'fval', 'ival', 'bval', 'dval') # Strip the FULL prefix and replace it with the simple # "attr" prefix data = { 'attr.{}'.format(_[0][prefix_len:]): { 'datatype': _[1], 'tval': _[2], 'fval': _[3], 'ival': _[4], 'bval': _[5], 'dval': _[6], } for _ in dballsubvalues } # for _ in dballsubvalues} # Append also the item itself data['attr'] = { # Replace the key (which may contain the separator) with the # simple "attr" key. In any case I do not need to return it! 'key': 'attr', 'datatype': attr.datatype, 'tval': attr.tval, 'fval': attr.fval, 'ival': attr.ival, 'bval': attr.bval, 'dval': attr.dval } return deserialize_attributes( data, sep=self._sep, original_class=self._model_class, original_pk=self.subspecifier_pk(attr))['attr'] data = { 'attr': { # Replace the key (which may contain the separator) with the # simple "attr" key. In any case I do not need to return it! 'key': 'attr', 'datatype': attr.datatype, 'tval': attr.tval, 'fval': attr.fval, 'ival': attr.ival, 'bval': attr.bval, 'dval': attr.dval } } return deserialize_attributes( data, sep=self._sep, original_class=self._model_class, original_pk=self.subspecifier_pk(attr))['attr'] except DeserializationException as exc: exc = DbContentError(exc) exc.original_exception = exc raise exc