def _classname_from_def(database, tablename): if database == 'disk': tablename_stripped = tablename[8:] if tablename[ 4] == 't' else tablename[9:] # iff ktbl return classname_from_table(database, tablename_stripped) else: # no ultimo support for now return None
def _table_to_schema(server, tables, table, datatypes_map, uml): subschema = {} subschema['link_table'] = True if table.lower().startswith('ktbl') else False subschema['classname'] = classname_from_table(server.server.database, table) subschema['subClassOf'] = None subschema['include'] = True columns = server.list_columns(table) primary_key = server.primary_key(table) if primary_key is not None: subschema['identifier'] = primary_key['COLUMN_NAME'] elif 'id' in [column['column_name'] for column in columns]: subschema['identifier'] = 'id' else: subschema['identifier'] = None if uml is None: relations = server.foreign_keys(table) attributes = server.list_columns(table, include_keys=False) else: relations = uml.relations_of(table) attributes = uml.attributes_of(table) subschema['relations'] = _relations_from_table(server, table, columns, tables, relations, uml) subschema['attributes'] = _attributes_from_table(table, columns, datatypes_map, attributes) return subschema
def _guess_table(server, name, tables): distances = [] for table in tables: classname = classname_from_table(server.server.database, table) distances.append((levenshtein(name, classname.lower()), table)) min_value = min(distances)[0] candidates = [k for v,k in distances if v == min_value] if len(candidates) > 1: return ("?" + "/".join(candidates) + "?", True) # question if value is less than 2.5 SDs from mean values = [v for v,_ in distances] if (mean(values)-min_value)/pstdev(values) < 2.5: return ("?" + candidates[0] + "?", True) return (candidates[0], False)
def _relations_from_table(server, table, columns, tables, schema_relations, uml): relations = {} valid_entries = [rel['column_name'] for rel in schema_relations] valid_values = [rel['referenced_table'] for rel in schema_relations] for column in columns: # if this is likely a link entry = column['column_name'] if entry in valid_entries: property_name = relationname_from_table(entry) if uml is None: referenced_table = valid_values[valid_entries.index(entry)] include = True else: referenced_table, unsure = _guess_table(server, property_name, tables) include = True if not unsure else False relations[entry] = {'property': property_name, 'subPropertyOf': None, 'targettable': referenced_table, 'targetclassname': classname_from_table(server.server.database, referenced_table), 'include': include} return relations
def _classname_from_def(database, definition): if definition['model'] == 'sql': return classname_from_table(database, definition['table']) else: return classname_from_layer(definition['table'])