def external_metadata_by_name(self, **kwargs: Any) -> FlaskResponse: """Gets table metadata from the source system and SQLAlchemy inspector""" try: params: ExternalMetadataParams = (ExternalMetadataSchema().load( kwargs.get("rison"))) except ValidationError as err: return json_error_response(str(err), status=400) datasource = ConnectorRegistry.get_datasource_by_name( session=db.session, datasource_type=params["datasource_type"], database_name=params["database_name"], schema=params["schema_name"], datasource_name=params["table_name"], ) try: if datasource is not None: # Get columns from Superset metadata external_metadata = datasource.external_metadata() else: # Use the SQLAlchemy inspector to get columns database = (db.session.query(Database).filter_by( database_name=params["database_name"]).one()) external_metadata = get_physical_table_metadata( database=database, table_name=params["table_name"], schema_name=params["schema_name"], ) except (NoResultFound, NoSuchTableError) as ex: raise DatasetNotFoundError() from ex return self.json_response(external_metadata)
def sync_columns(self) -> None: """Sync table columns with the database. Keep metadata for existing columns""" try: column_metadata = get_physical_table_metadata( self.database, self.name, self.schema ) except Exception: # pylint: disable=broad-except column_metadata = [] existing_columns = {column.name: column for column in self.columns} quote_identifier = self.database.quote_identifier def update_or_create_column(column_meta: Dict[str, Any]) -> Column: column_name: str = column_meta["name"] if column_name in existing_columns: column = existing_columns[column_name] else: column = Column(name=column_name) column.type = column_meta["type"] column.is_temporal = column_meta["is_dttm"] column.expression = quote_identifier(column_name) column.is_aggregation = False column.is_physical = True column.is_spatial = False column.is_partition = False # TODO: update with accurate is_partition return column self.columns = [update_or_create_column(col) for col in column_metadata]
def external_metadata_by_name( self, datasource_type: str, database_name: str, schema_name: str, table_name: str, ) -> FlaskResponse: """Gets table metadata from the source system and SQLAlchemy inspector""" database_name = parse_js_uri_path_item(database_name) or "" schema_name = parse_js_uri_path_item(schema_name, eval_undefined=True) or "" table_name = parse_js_uri_path_item(table_name) or "" datasource = ConnectorRegistry.get_datasource_by_name( session=db.session, datasource_type=datasource_type, database_name=database_name, schema=schema_name, datasource_name=table_name, ) try: if datasource is not None: external_metadata = datasource.external_metadata() else: # Use the SQLAlchemy inspector to get columns database = ( db.session.query(Database) .filter_by(database_name=database_name) .one() ) external_metadata = get_physical_table_metadata( database=database, table_name=table_name, schema_name=schema_name, ) except SupersetException as ex: return json_error_response(str(ex), status=400) return self.json_response(external_metadata)