Beispiel #1
0
    def save(self) -> FlaskResponse:
        data = request.form.get("data")
        if not isinstance(data, str):
            return json_error_response(_("Request missing data field."),
                                       status=500)

        datasource_dict = json.loads(data)
        datasource_id = datasource_dict.get("id")
        datasource_type = datasource_dict.get("type")
        database_id = datasource_dict["database"].get("id")
        orm_datasource = ConnectorRegistry.get_datasource(
            datasource_type, datasource_id, db.session)
        orm_datasource.database_id = database_id

        if "owners" in datasource_dict and orm_datasource.owner_class is not None:
            # Check ownership
            if app.config["OLD_API_CHECK_DATASET_OWNERSHIP"]:
                # mimic the behavior of the new dataset command that
                # checks ownership and ensures that non-admins aren't locked out
                # of the object
                try:
                    check_ownership(orm_datasource)
                except SupersetSecurityException as ex:
                    raise DatasetForbiddenError() from ex
                user = security_manager.get_user_by_id(g.user.id)
                datasource_dict["owners"] = populate_owners(
                    user, datasource_dict["owners"], default_to_user=False)
            else:
                # legacy behavior
                datasource_dict["owners"] = (db.session.query(
                    orm_datasource.owner_class).filter(
                        orm_datasource.owner_class.id.in_(
                            datasource_dict["owners"] or [])).all())

        duplicates = [
            name for name, count in Counter(
                [col["column_name"]
                 for col in datasource_dict["columns"]]).items() if count > 1
        ]
        if duplicates:
            return json_error_response(
                _(
                    "Duplicate column name(s): %(columns)s",
                    columns=",".join(duplicates),
                ),
                status=409,
            )
        orm_datasource.update_from_object(datasource_dict)
        data = orm_datasource.data
        db.session.commit()

        return self.json_response(data)
Beispiel #2
0
    def save(self) -> FlaskResponse:
        data = request.form.get("data")
        if not isinstance(data, str):
            return json_error_response(_("Request missing data field."), status=500)

        datasource_dict = json.loads(data)
        datasource_id = datasource_dict.get("id")
        datasource_type = datasource_dict.get("type")
        database_id = datasource_dict["database"].get("id")
        orm_datasource = ConnectorRegistry.get_datasource(
            datasource_type, datasource_id, db.session
        )
        orm_datasource.database_id = database_id

        if "owners" in datasource_dict and orm_datasource.owner_class is not None:
            # Check ownership
            if app.config["OLD_API_CHECK_DATASET_OWNERSHIP"]:
                try:
                    check_ownership(orm_datasource)
                except SupersetSecurityException:
                    raise DatasetForbiddenError()

            datasource_dict["owners"] = (
                db.session.query(orm_datasource.owner_class)
                .filter(orm_datasource.owner_class.id.in_(datasource_dict["owners"]))
                .all()
            )

        duplicates = [
            name
            for name, count in Counter(
                [col["column_name"] for col in datasource_dict["columns"]]
            ).items()
            if count > 1
        ]
        if duplicates:
            return json_error_response(
                _(
                    "Duplicate column name(s): %(columns)s",
                    columns=",".join(duplicates),
                ),
                status=409,
            )
        orm_datasource.update_from_object(datasource_dict)
        data = orm_datasource.data
        db.session.commit()

        return self.json_response(data)
Beispiel #3
0
    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)
Beispiel #4
0
 def get_value(self, key_id: int) -> FlaskResponse:  # pylint: disable=no-self-use
     try:
         kv = db.session.query(models.KeyValue).filter_by(id=key_id).scalar()
         if not kv:
             return Response(status=404, content_type="text/plain")
     except Exception as ex:  # pylint: disable=broad-except
         return json_error_response(utils.error_msg_from_exception(ex))
     return Response(kv.value, status=200, content_type="text/plain")
Beispiel #5
0
 def store(self) -> FlaskResponse:  # pylint: disable=no-self-use
     try:
         value = request.form.get("data")
         obj = models.KeyValue(value=value)
         db.session.add(obj)
         db.session.commit()
     except Exception as ex:  # pylint: disable=broad-except
         return json_error_response(utils.error_msg_from_exception(ex))
     return Response(json.dumps({"id": obj.id}), status=200)
Beispiel #6
0
    def save(self) -> FlaskResponse:
        data = request.form.get("data")
        if not isinstance(data, str):
            return json_error_response(_("Request missing data field."),
                                       status=500)

        datasource_dict = json.loads(data)
        datasource_id = datasource_dict.get("id")
        datasource_type = datasource_dict.get("type")
        database_id = datasource_dict["database"].get("id")
        orm_datasource = ConnectorRegistry.get_datasource(
            datasource_type, datasource_id, db.session)
        orm_datasource.database_id = database_id

        if "owners" in datasource_dict and orm_datasource.owner_class is not None:
            # Check ownership
            try:
                check_ownership(orm_datasource)
            except SupersetSecurityException as ex:
                raise DatasetForbiddenError() from ex

        user = security_manager.get_user_by_id(g.user.id)
        datasource_dict["owners"] = populate_owners(user,
                                                    datasource_dict["owners"],
                                                    default_to_user=False)

        duplicates = [
            name for name, count in Counter(
                [col["column_name"]
                 for col in datasource_dict["columns"]]).items() if count > 1
        ]
        if duplicates:
            return json_error_response(
                _(
                    "Duplicate column name(s): %(columns)s",
                    columns=",".join(duplicates),
                ),
                status=409,
            )
        orm_datasource.update_from_object(datasource_dict)
        data = orm_datasource.data
        db.session.commit()

        return self.json_response(sanitize_datasource_data(data))
Beispiel #7
0
 def external_metadata(self, datasource_type: str,
                       datasource_id: int) -> FlaskResponse:
     """Gets column info from the source system"""
     datasource = ConnectorRegistry.get_datasource(datasource_type,
                                                   datasource_id,
                                                   db.session)
     try:
         external_metadata = datasource.external_metadata()
     except SupersetException as ex:
         return json_error_response(str(ex), status=400)
     return self.json_response(external_metadata)
Beispiel #8
0
    def samples(self) -> FlaskResponse:
        try:
            params = SamplesRequestSchema().load(request.args)
            payload = SamplesPayloadSchema().load(request.json)
        except ValidationError as err:
            return json_error_response(err.messages, status=400)

        rv = get_samples(
            datasource_type=params["datasource_type"],
            datasource_id=params["datasource_id"],
            force=params["force"],
            page=params["page"],
            per_page=params["per_page"],
            payload=payload,
        )
        return self.json_response({"result": rv})