def get(self, request, schema, table): """ Returns a dictionary that describes the DDL-make-up of this table. Fields are: * name : Name of the table, * schema: Name of the schema, * columns : as specified in :meth:`api.actions.describe_columns` * indexes : as specified in :meth:`api.actions.describe_indexes` * constraints: as specified in :meth:`api.actions.describe_constraints` :param request: :return: """ schema, table = actions.get_table_name(schema, table, restrict_schemas=False) return JsonResponse( { "schema": schema, "name": table, "columns": actions.describe_columns(schema, table), "indexed": actions.describe_indexes(schema, table), "constraints": actions.describe_constraints(schema, table), } )
def get(self, request, schema, table): # get the columns id from the schema and the table columns = [(c, c) for c in describe_columns(schema, table).keys()] formset = GraphViewForm(columns=columns) return render(request, 'dataedit/tablegraph_form.html', {'formset': formset})
def get(self, request, schema, table, column=None): schema, table = actions.get_table_name(schema, table, restrict_schemas=False) response = actions.describe_columns(schema, table) if column: try: response = response[column] except KeyError: raise actions.APIError('The column specified is not part of ' 'this table.') return JsonResponse(response)
def get(self, request, schema, table, maptype): columns = [(c, c) for c in describe_columns(schema, table).keys()] if maptype == "latlon": form = LatLonViewForm(columns=columns) elif maptype == "geom": form = GeomViewForm(columns=columns) else: raise Http404 return render(request, 'dataedit/tablemap_form.html', {'form': form})
def post(self, request, schema, table, maptype): columns = [(c, c) for c in describe_columns(schema, table).keys()] if maptype == "latlon": form = LatLonViewForm(request.POST, columns=columns) options = dict(lat=request.POST.get('lat'), lon=request.POST.get('lon')) elif maptype == "geom": form = GeomViewForm(request.POST, columns=columns) options = dict(geom=request.POST.get('geom')) else: raise Http404 form.schema = schema form.table = table form.options = options if form.is_valid(): view_id = form.save(commit=True) return redirect( "/dataedit/view/{schema}/{table}?view={view_id}".format( schema=schema, table=table, view_id=view_id)) else: return self.get(request, schema, table)
def change_requests(schema, table): """ Loads the dataedit admin interface :param request: :return: """ # I want to display old and new data, if different. display_message = None api_columns = dba.get_column_changes(reviewed=False, schema=schema, table=table) api_constraints = dba.get_constraints_changes(reviewed=False, schema=schema, table=table) # print(api_columns) # print(api_constraints) cache = dict() data = dict() data['api_columns'] = {} data['api_constraints'] = {} keyword_whitelist = [ 'column_name', 'c_table', 'c_schema', 'reviewed', 'changed', 'id' ] old_description = dba.describe_columns(schema, table) for change in api_columns: name = change['column_name'] id = change['id'] # Identifing over 'new'. if change.get('new_name') is not None: change['column_name'] = change['new_name'] old_cd = old_description.get(name) data['api_columns'][id] = {} data['api_columns'][id]['old'] = {} if old_cd is not None: old = api.parser.parse_scolumnd_from_columnd( schema, table, name, old_description.get(name)) for key in list(change): value = change[key] if key not in keyword_whitelist and (value is None or value == old[key]): old.pop(key) change.pop(key) data['api_columns'][id]['old'] = old else: data['api_columns'][id]['old']['c_schema'] = schema data['api_columns'][id]['old']['c_table'] = table data['api_columns'][id]['old']['column_name'] = name data['api_columns'][id]['new'] = change for i in range(len(api_constraints)): value = api_constraints[i] id = value.get('id') if value.get('reference_table') is None or value.get( 'reference_column') is None: value.pop('reference_table') value.pop('reference_column') data['api_constraints'][id] = value display_style = [ 'c_schema', 'c_table', 'column_name', 'not_null', 'data_type', 'reference_table', 'constraint_parameter', 'reference_column', 'action', 'constraint_type', 'constraint_name' ] return { 'data': data, 'display_items': display_style, 'display_message': display_message }
def get_column_description(schema, table): """Return list of column descriptions: [{ "name": str, "data_type": str, "is_nullable': bool, "is_pk": bool }] """ def get_datatype_str(column_def): """get single string sql type definition. We want the data type definition to be a simple string, e.g. decimal(10, 6) or varchar(128), so we need to combine the various fields (type, numeric_precision, numeric_scale, ...) """ # for reverse validation, see also api.parser.parse_type(dt_string) dt = column_def['data_type'].lower() precisions = None if dt.startswith('character'): if dt == 'character varying': dt = 'varchar' else: dt = 'char' precisions = [column_def['character_maximum_length']] elif dt.endswith(' without time zone'): # this is the default dt = dt.replace(' without time zone', '') elif re.match('(numeric|decimal)', dt): precisions = [ column_def['numeric_precision'], column_def['numeric_scale'] ] elif dt == 'interval': precisions = [column_def['interval_precision']] elif re.match('.*int', dt) and re.match( 'nextval', column_def.get('column_default') or ''): #dt = dt.replace('int', 'serial') pass elif dt.startswith('double'): dt = 'float' if precisions: # remove None precisions = [x for x in precisions if x is not None] if precisions: dt += '(%s)' % ', '.join(str(x) for x in precisions) return dt def get_pk_fields(constraints): """Get the column names that make up the primary key from the constraints definitions. NOTE: Currently, the wizard to create tables only supports single fields primary keys (which is advisable anyways) """ pk_fields = [] for _name, constraint in constraints.items(): if constraint.get("constraint_type") == "PRIMARY KEY": m = re.match(r"PRIMARY KEY[ ]*\(([^)]+)", constraint.get("definition") or "") if m: # "f1, f2" -> ["f1", "f2"] pk_fields = [x.strip() for x in m.groups()[0].split(',')] return pk_fields _columns = actions.describe_columns(schema, table) _constraints = actions.describe_constraints(schema, table) pk_fields = get_pk_fields(_constraints) # order by ordinal_position columns = [] for name, col in sorted(_columns.items(), key=lambda kv: int(kv[1]['ordinal_position'])): columns.append({ 'name': name, 'data_type': get_datatype_str(col), 'is_nullable': col['is_nullable'], 'is_pk': name in pk_fields }) return columns
def change_requests(schema, table): """ Loads the dataedit admin interface :param request: :return: """ # I want to display old and new data, if different. display_message = None api_columns = actions.get_column_changes(reviewed=False, schema=schema, table=table) api_constraints = actions.get_constraints_changes(reviewed=False, schema=schema, table=table) # print(api_columns) # print(api_constraints) cache = dict() data = dict() data["api_columns"] = {} data["api_constraints"] = {} keyword_whitelist = [ "column_name", "c_table", "c_schema", "reviewed", "changed", "id", ] old_description = actions.describe_columns(schema, table) for change in api_columns: name = change["column_name"] id = change["id"] # Identifing over 'new'. if change.get("new_name") is not None: change["column_name"] = change["new_name"] old_cd = old_description.get(name) data["api_columns"][id] = {} data["api_columns"][id]["old"] = {} if old_cd is not None: old = api.parser.parse_scolumnd_from_columnd( schema, table, name, old_description.get(name)) for key in list(change): value = change[key] if key not in keyword_whitelist and (value is None or value == old[key]): old.pop(key) change.pop(key) data["api_columns"][id]["old"] = old else: data["api_columns"][id]["old"]["c_schema"] = schema data["api_columns"][id]["old"]["c_table"] = table data["api_columns"][id]["old"]["column_name"] = name data["api_columns"][id]["new"] = change for i in range(len(api_constraints)): value = api_constraints[i] id = value.get("id") if (value.get("reference_table") is None or value.get("reference_column") is None): value.pop("reference_table") value.pop("reference_column") data["api_constraints"][id] = value display_style = [ "c_schema", "c_table", "column_name", "not_null", "data_type", "reference_table", "constraint_parameter", "reference_column", "action", "constraint_type", "constraint_name", ] return { "data": data, "display_items": display_style, "display_message": display_message, }