def get_datasource(cls, datasource_type: str, datasource_id: int, session: Session) -> "BaseDatasource": """Safely get a datasource instance, raises `DatasetNotFoundError` if `datasource_type` is not registered or `datasource_id` does not exist.""" if datasource_type not in cls.sources: raise DatasetNotFoundError() datasource = (session.query(cls.sources[datasource_type]).filter_by( id=datasource_id).one_or_none()) if not datasource: raise DatasetNotFoundError() return datasource
def validate(self) -> None: exceptions = list() owner_ids: Optional[List[int]] = self._properties.get("owners") # Validate/populate model exists self._model = DatasetDAO.find_by_id(self._model_id) if not self._model: raise DatasetNotFoundError() # Check ownership try: check_ownership(self._model) except SupersetSecurityException: raise DatasetForbiddenError() database_id = self._properties.get("database", None) table_name = self._properties.get("table_name", None) # Validate uniqueness if not DatasetDAO.validate_update_uniqueness( self._model.database_id, self._model_id, table_name): exceptions.append(DatasetExistsValidationError(table_name)) # Validate/Populate database not allowed to change if database_id and database_id != self._model: exceptions.append(DatabaseChangeValidationError()) # Validate/Populate owner try: owners = populate_owners(self._actor, owner_ids) self._properties["owners"] = owners except ValidationError as e: exceptions.append(e) if exceptions: exception = DatasetInvalidError() exception.add_list(exceptions) raise exception
def dataset_macro( dataset_id: int, include_metrics: bool = False, columns: Optional[List[str]] = None, ) -> str: """ Given a dataset ID, return the SQL that represents it. The generated SQL includes all columns (including computed) by default. Optionally the user can also request metrics to be included, and columns to group by. """ # pylint: disable=import-outside-toplevel from superset.datasets.dao import DatasetDAO dataset = DatasetDAO.find_by_id(dataset_id) if not dataset: raise DatasetNotFoundError(f"Dataset {dataset_id} not found!") columns = columns or [column.column_name for column in dataset.columns] metrics = [metric.metric_name for metric in dataset.metrics] query_obj = { "is_timeseries": False, "filter": [], "metrics": metrics if include_metrics else None, "columns": columns, } sqla_query = dataset.get_query_str_extended(query_obj) sql = sqla_query.sql return f"({sql}) AS dataset_{dataset_id}"
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 check_dataset_access(dataset_id: int) -> Optional[bool]: if dataset_id: dataset = DatasetDAO.find_by_id(dataset_id) if dataset: can_access_datasource = security_manager.can_access_datasource(dataset) if can_access_datasource: return True raise DatasetAccessDeniedError() raise DatasetNotFoundError()
def validate(self) -> None: # Validate/populate model exists self._model = DatasetDAO.find_by_id(self._model_id) if not self._model: raise DatasetNotFoundError() # Check ownership try: check_ownership(self._model) except SupersetSecurityException: raise DatasetForbiddenError()
def check_dataset_access(dataset_id: int) -> Optional[bool]: if dataset_id: # Access checks below, no need to validate them twice as they can be expensive. dataset = DatasetDAO.find_by_id(dataset_id, skip_base_filter=True) if dataset: can_access_datasource = security_manager.can_access_datasource(dataset) if can_access_datasource: return True raise DatasetAccessDeniedError() raise DatasetNotFoundError()
def validate(self) -> None: # Validate/populate model exists self._models = DatasetDAO.find_by_ids(self._model_ids) if not self._models or len(self._models) != len(self._model_ids): raise DatasetNotFoundError() # Check ownership for model in self._models: try: security_manager.raise_for_ownership(model) except SupersetSecurityException as ex: raise DatasetForbiddenError() from ex
def run(self) -> Dict[str, Any]: self.validate() if not self._model: raise DatasetNotFoundError() qc_instance = QueryContextFactory().create( datasource={ "type": self._model.type, "id": self._model.id, }, queries=[{}], result_type=ChartDataResultType.SAMPLES, force=self._force, ) results = qc_instance.get_payload() try: return results["queries"][0] except (IndexError, KeyError) as exc: raise DatasetSamplesFailedError from exc
def validate(self) -> None: exceptions: List[ValidationError] = [] owner_ids: Optional[List[int]] = self._properties.get("owners") # Validate/populate model exists self._model = DatasetDAO.find_by_id(self._model_id) if not self._model: raise DatasetNotFoundError() # Check ownership try: security_manager.raise_for_ownership(self._model) except SupersetSecurityException as ex: raise DatasetForbiddenError() from ex database_id = self._properties.get("database", None) table_name = self._properties.get("table_name", None) # Validate uniqueness if not DatasetDAO.validate_update_uniqueness( self._model.database_id, self._model_id, table_name): exceptions.append(DatasetExistsValidationError(table_name)) # Validate/Populate database not allowed to change if database_id and database_id != self._model: exceptions.append(DatabaseChangeValidationError()) # Validate/Populate owner try: owners = self.populate_owners(owner_ids) self._properties["owners"] = owners except ValidationError as ex: exceptions.append(ex) # Validate columns columns = self._properties.get("columns") if columns: self._validate_columns(columns, exceptions) # Validate metrics metrics = self._properties.get("metrics") if metrics: self._validate_metrics(metrics, exceptions) if exceptions: exception = DatasetInvalidError() exception.add_list(exceptions) raise exception
def validate(self) -> None: self._models = DatasetDAO.find_by_ids(self.dataset_ids) if len(self._models) != len(self.dataset_ids): raise DatasetNotFoundError()