示例#1
0
 def __init__(
         self,
         datasource: Dict,
         queries: List[Dict],
 ):
     self.datasource = ConnectorRegistry.get_datasource(datasource.get('type'),
                                                        int(datasource.get('id')),
                                                        db.session)
     self.queries = list(map(lambda query_obj: QueryObject(**query_obj), queries))
示例#2
0
    def __init__(
            self,
            datasource: Dict,
            queries: List[Dict],
            force: bool = False,
            custom_cache_timeout: int = None,
    ):
        self.datasource = ConnectorRegistry.get_datasource(datasource.get('type'),
                                                           int(datasource.get('id')),
                                                           db.session)
        self.queries = list(map(lambda query_obj: QueryObject(**query_obj), queries))

        self.force = force

        self.custom_cache_timeout = custom_cache_timeout

        self.enforce_numerical_metrics = True
    def save(self):
        datasource = json.loads(request.form.get('data'))
        datasource_id = datasource.get('id')
        datasource_type = datasource.get('type')
        orm_datasource = ConnectorRegistry.get_datasource(
            datasource_type, datasource_id, db.session)

        if not check_ownership(orm_datasource, raise_if_false=False):
            return json_error_response(
                __(
                    'You are not authorized to modify '
                    'this data source configuration'),
                status='401',
            )
        orm_datasource.update_from_object(datasource)
        data = orm_datasource.data
        db.session.commit()
        return self.json_response(data)
示例#4
0
def get_viz(
    slice_id=None,
    form_data=None,
    datasource_type=None,
    datasource_id=None,
    force=False,
):
    if slice_id:
        slc = (db.session.query(models.Slice).filter_by(id=slice_id).one())
        return slc.get_viz()
    else:
        viz_type = form_data.get('viz_type', 'table')
        datasource = ConnectorRegistry.get_datasource(datasource_type,
                                                      datasource_id,
                                                      db.session)
        viz_obj = viz.viz_types[viz_type](
            datasource,
            form_data=form_data,
            force=force,
        )
        return viz_obj
示例#5
0
 def __init__(  # pylint: disable=too-many-arguments
     self,
     datasource: DatasourceDict,
     queries: List[Dict[str, Any]],
     force: bool = False,
     custom_cache_timeout: Optional[int] = None,
     result_type: Optional[ChartDataResultType] = None,
     result_format: Optional[ChartDataResultFormat] = None,
 ) -> None:
     self.datasource = ConnectorRegistry.get_datasource(
         str(datasource["type"]), int(datasource["id"]), db.session)
     self.queries = [QueryObject(**query_obj) for query_obj in queries]
     self.force = force
     self.custom_cache_timeout = custom_cache_timeout
     self.result_type = result_type or ChartDataResultType.FULL
     self.result_format = result_format or ChartDataResultFormat.JSON
     self.cache_values = {
         "datasource": datasource,
         "queries": queries,
         "result_type": self.result_type,
         "result_format": self.result_format,
     }
    def save(self):
        datasource = json.loads(request.form.get('data'))
        datasource_id = datasource.get('id')
        datasource_type = datasource.get('type')
        orm_datasource = ConnectorRegistry.get_datasource(
            datasource_type, datasource_id, db.session)

        if not check_ownership(orm_datasource, raise_if_false=False):
            return json_error_response(
                __(
                    'You are not authorized to modify '
                    'this data source configuration'),
                status='401',
            )

        if 'owners' in datasource:
            datasource['owners'] = db.session.query(orm_datasource.owner_class).filter(
                orm_datasource.owner_class.id.in_(datasource['owners'])).all()
        orm_datasource.update_from_object(datasource)
        data = orm_datasource.data
        db.session.commit()
        return self.json_response(data)
示例#7
0
 def external_metadata(
     self, datasource_type: str, datasource_id: int
 ) -> FlaskResponse:
     """Gets column info from the source system"""
     if datasource_type == "druid":
         datasource = ConnectorRegistry.get_datasource(
             datasource_type, datasource_id, db.session
         )
     elif datasource_type == "table":
         database = (
             db.session.query(Database).filter_by(id=request.args.get("db_id")).one()
         )
         table_class = ConnectorRegistry.sources["table"]
         datasource = table_class(
             database=database,
             table_name=request.args.get("table_name"),
             schema=request.args.get("schema") or None,
         )
     else:
         raise Exception(f"Unsupported datasource_type: {datasource_type}")
     external_metadata = datasource.external_metadata()
     return self.json_response(external_metadata)
示例#8
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:
            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(
                f"Duplicate column name(s): {','.join(duplicates)}", status=409
            )
        orm_datasource.update_from_object(datasource_dict)
        data = orm_datasource.data
        db.session.commit()

        return self.json_response(data)
示例#9
0
    def test_query_cache_key_changes_when_metric_is_updated(self):
        self.login(username="******")
        payload = get_query_context("birth_names")

        # make temporary change and revert it to refresh the changed_on property
        datasource = ConnectorRegistry.get_datasource(
            datasource_type=payload["datasource"]["type"],
            datasource_id=payload["datasource"]["id"],
            session=db.session,
        )

        datasource.metrics.append(
            SqlMetric(metric_name="foo", expression="select 1;"))
        db.session.commit()

        # construct baseline query_cache_key
        query_context = ChartDataQueryContextSchema().load(payload)
        query_object = query_context.queries[0]
        cache_key_original = query_context.query_cache_key(query_object)

        # wait a second since mysql records timestamps in second granularity
        time.sleep(1)

        datasource.metrics[0].expression = "select 2;"
        db.session.commit()

        # create new QueryContext with unchanged attributes, extract new query_cache_key
        query_context = ChartDataQueryContextSchema().load(payload)
        query_object = query_context.queries[0]
        cache_key_new = query_context.query_cache_key(query_object)

        datasource.metrics = []
        db.session.commit()

        # the new cache_key should be different due to updated datasource
        self.assertNotEqual(cache_key_original, cache_key_new)
示例#10
0
文件: utils.py 项目: tan31989/caravel
def get_viz(
        slice_id=None,
        form_data=None,
        datasource_type=None,
        datasource_id=None,
        force=False,
):
    if slice_id:
        slc = (
            db.session.query(models.Slice)
            .filter_by(id=slice_id)
            .one()
        )
        return slc.get_viz()
    else:
        viz_type = form_data.get('viz_type', 'table')
        datasource = ConnectorRegistry.get_datasource(
            datasource_type, datasource_id, db.session)
        viz_obj = viz.viz_types[viz_type](
            datasource,
            form_data=form_data,
            force=force,
        )
        return viz_obj
示例#11
0
 def _convert_to_model(self, datasource: DatasourceDict) -> BaseDatasource:
     return ConnectorRegistry.get_datasource(str(datasource["type"]),
                                             int(datasource["id"]),
                                             db.session)
示例#12
0
 def get(self, datasource_type: str, datasource_id: int) -> FlaskResponse:
     datasource = ConnectorRegistry.get_datasource(datasource_type,
                                                   datasource_id,
                                                   db.session)
     return self.json_response(datasource.data)
示例#13
0
    def __init__(
        self,
        datasource: Optional[DatasourceDict] = None,
        result_type: Optional[ChartDataResultType] = None,
        annotation_layers: Optional[List[Dict[str, Any]]] = None,
        applied_time_extras: Optional[Dict[str, str]] = None,
        apply_fetch_values_predicate: bool = False,
        granularity: Optional[str] = None,
        metrics: Optional[List[Union[Dict[str, Any], str]]] = None,
        groupby: Optional[List[str]] = None,
        filters: Optional[List[Dict[str, Any]]] = None,
        time_range: Optional[str] = None,
        time_shift: Optional[str] = None,
        is_timeseries: Optional[bool] = None,
        timeseries_limit: int = 0,
        row_limit: Optional[int] = None,
        row_offset: Optional[int] = None,
        timeseries_limit_metric: Optional[Metric] = None,
        order_desc: bool = True,
        extras: Optional[Dict[str, Any]] = None,
        columns: Optional[List[str]] = None,
        orderby: Optional[List[OrderBy]] = None,
        post_processing: Optional[List[Optional[Dict[str, Any]]]] = None,
        is_rowcount: bool = False,
        **kwargs: Any,
    ):
        columns = columns or []
        groupby = groupby or []
        extras = extras or {}
        annotation_layers = annotation_layers or []

        self.is_rowcount = is_rowcount
        self.datasource = None
        if datasource:
            self.datasource = ConnectorRegistry.get_datasource(
                str(datasource["type"]), int(datasource["id"]), db.session)
        self.result_type = result_type
        self.apply_fetch_values_predicate = apply_fetch_values_predicate or False
        self.annotation_layers = [
            layer for layer in annotation_layers
            # formula annotations don't affect the payload, hence can be dropped
            if layer["annotationType"] != "FORMULA"
        ]
        self.applied_time_extras = applied_time_extras or {}
        self.granularity = granularity
        self.from_dttm, self.to_dttm = get_since_until(
            relative_start=extras.get("relative_start",
                                      config["DEFAULT_RELATIVE_START_TIME"]),
            relative_end=extras.get("relative_end",
                                    config["DEFAULT_RELATIVE_END_TIME"]),
            time_range=time_range,
            time_shift=time_shift,
        )
        # is_timeseries is True if time column is in either columns or groupby
        # (both are dimensions)
        self.is_timeseries = (is_timeseries if is_timeseries is not None else
                              DTTM_ALIAS in columns + groupby)
        self.time_range = time_range
        self.time_shift = parse_human_timedelta(time_shift)
        self.post_processing = [
            post_proc for post_proc in post_processing or [] if post_proc
        ]

        # Support metric reference/definition in the format of
        #   1. 'metric_name'   - name of predefined metric
        #   2. { label: 'label_name' }  - legacy format for a predefined metric
        #   3. { expressionType: 'SIMPLE' | 'SQL', ... } - adhoc metric
        self.metrics = metrics and [
            x if isinstance(x, str) or is_adhoc_metric(x) else
            x["label"]  # type: ignore
            for x in metrics
        ]

        self.row_limit = config["ROW_LIMIT"] if row_limit is None else row_limit
        self.row_offset = row_offset or 0
        self.filter = filters or []
        self.timeseries_limit = timeseries_limit
        self.timeseries_limit_metric = timeseries_limit_metric
        self.order_desc = order_desc
        self.extras = extras

        if config["SIP_15_ENABLED"]:
            self.extras["time_range_endpoints"] = get_time_range_endpoints(
                form_data=self.extras)

        self.columns = columns
        self.groupby = groupby or []
        self.orderby = orderby or []

        # rename deprecated fields
        for field in DEPRECATED_FIELDS:
            if field.old_name in kwargs:
                logger.warning(
                    "The field `%s` is deprecated, please use `%s` instead.",
                    field.old_name,
                    field.new_name,
                )
                value = kwargs[field.old_name]
                if value:
                    if hasattr(self, field.new_name):
                        logger.warning(
                            "The field `%s` is already populated, "
                            "replacing value with contents from `%s`.",
                            field.new_name,
                            field.old_name,
                        )
                    setattr(self, field.new_name, value)

        # move deprecated extras fields to extras
        for field in DEPRECATED_EXTRAS_FIELDS:
            if field.old_name in kwargs:
                logger.warning(
                    "The field `%s` is deprecated and should "
                    "be passed to `extras` via the `%s` property.",
                    field.old_name,
                    field.new_name,
                )
                value = kwargs[field.old_name]
                if value:
                    if hasattr(self.extras, field.new_name):
                        logger.warning(
                            "The field `%s` is already populated in "
                            "`extras`, replacing value with contents "
                            "from `%s`.",
                            field.new_name,
                            field.old_name,
                        )
                    self.extras[field.new_name] = value
示例#14
0
from superset.connectors.connector_registry import ConnectorRegistry
from flask_appbuilder.security.sqla.models import User
from superset.viz import TableViz
from superset import db
from flask import g
import json

f = open('d:\\home\\pivot_viz\\form_data.json')
form_data_json = f.read()
f.close()

g.user = db.session.query(User).filter(User.id == 2).one()
form_data = json.loads(form_data_json)
datasource_type = form_data.get('viz_type', 'table')
datasource_id = form_data['datasource'].split('__')[0]
datasource = ConnectorRegistry.get_datasource(datasource_type, datasource_id,
                                              db.session)
viz = TableViz(datasource, form_data)
res = viz.get_payload(force=True)
# print(res)
with open('d:\\home\\pivot_viz\\response.json', 'w', encoding='utf8') as f:
    f.write(viz.json_dumps(res))
示例#15
0
    def __init__(  # pylint: disable=too-many-arguments,too-many-locals
        self,
        query_context: "QueryContext",
        annotation_layers: Optional[List[Dict[str, Any]]] = None,
        applied_time_extras: Optional[Dict[str, str]] = None,
        apply_fetch_values_predicate: bool = False,
        columns: Optional[List[str]] = None,
        datasource: Optional[DatasourceDict] = None,
        extras: Optional[Dict[str, Any]] = None,
        filters: Optional[List[QueryObjectFilterClause]] = None,
        granularity: Optional[str] = None,
        is_rowcount: bool = False,
        is_timeseries: Optional[bool] = None,
        metrics: Optional[List[Metric]] = None,
        order_desc: bool = True,
        orderby: Optional[List[OrderBy]] = None,
        post_processing: Optional[List[Optional[Dict[str, Any]]]] = None,
        result_type: Optional[ChartDataResultType] = None,
        row_limit: Optional[int] = None,
        row_offset: Optional[int] = None,
        series_columns: Optional[List[str]] = None,
        series_limit: int = 0,
        series_limit_metric: Optional[Metric] = None,
        time_range: Optional[str] = None,
        time_shift: Optional[str] = None,
        **kwargs: Any,
    ):
        columns = columns or []
        extras = extras or {}
        annotation_layers = annotation_layers or []
        self.time_offsets = kwargs.get("time_offsets", [])
        self.inner_from_dttm = kwargs.get("inner_from_dttm")
        self.inner_to_dttm = kwargs.get("inner_to_dttm")
        if series_columns:
            self.series_columns = series_columns
        elif is_timeseries and metrics:
            self.series_columns = columns
        else:
            self.series_columns = []

        self.is_rowcount = is_rowcount
        self.datasource = None
        if datasource:
            self.datasource = ConnectorRegistry.get_datasource(
                str(datasource["type"]), int(datasource["id"]), db.session)
        self.result_type = result_type or query_context.result_type
        self.apply_fetch_values_predicate = apply_fetch_values_predicate or False
        self.annotation_layers = [
            layer for layer in annotation_layers
            # formula annotations don't affect the payload, hence can be dropped
            if layer["annotationType"] != "FORMULA"
        ]
        self.applied_time_extras = applied_time_extras or {}
        self.granularity = granularity
        self.from_dttm, self.to_dttm = get_since_until(
            relative_start=extras.get("relative_start",
                                      config["DEFAULT_RELATIVE_START_TIME"]),
            relative_end=extras.get("relative_end",
                                    config["DEFAULT_RELATIVE_END_TIME"]),
            time_range=time_range,
            time_shift=time_shift,
        )
        # is_timeseries is True if time column is in either columns or groupby
        # (both are dimensions)
        self.is_timeseries = (is_timeseries if is_timeseries is not None else
                              DTTM_ALIAS in columns)
        self.time_range = time_range
        self.time_shift = parse_human_timedelta(time_shift)
        self.post_processing = [
            post_proc for post_proc in post_processing or [] if post_proc
        ]

        # Support metric reference/definition in the format of
        #   1. 'metric_name'   - name of predefined metric
        #   2. { label: 'label_name' }  - legacy format for a predefined metric
        #   3. { expressionType: 'SIMPLE' | 'SQL', ... } - adhoc metric
        self.metrics = metrics and [
            x if isinstance(x, str) or is_adhoc_metric(x) else
            x["label"]  # type: ignore
            for x in metrics
        ]

        default_row_limit = (config["SAMPLES_ROW_LIMIT"]
                             if self.result_type == ChartDataResultType.SAMPLES
                             else config["ROW_LIMIT"])
        self.row_limit = apply_max_row_limit(row_limit or default_row_limit)
        self.row_offset = row_offset or 0
        self.filter = filters or []
        self.series_limit = series_limit
        self.series_limit_metric = series_limit_metric
        self.order_desc = order_desc
        self.extras = extras

        if config["SIP_15_ENABLED"]:
            self.extras["time_range_endpoints"] = get_time_range_endpoints(
                form_data=self.extras)

        self.columns = columns
        self.orderby = orderby or []

        self._rename_deprecated_fields(kwargs)
        self._move_deprecated_extra_fields(kwargs)
示例#16
0
 def external_metadata(self, datasource_type=None, datasource_id=None):
     """Gets column info from the source system"""
     orm_datasource = ConnectorRegistry.get_datasource(
         datasource_type, datasource_id, db.session)
     return self.json_response(orm_datasource.external_metadata())
示例#17
0
def get_datasource_by_id(datasource_id: int,
                         datasource_type: str) -> BaseDatasource:
    try:
        return ConnectorRegistry.get_datasource(datasource_type, datasource_id)
    except (NoResultFound, KeyError):
        raise DatasourceNotFoundValidationError()
示例#18
0
 def external_metadata(self, datasource_type=None, datasource_id=None):
     """Gets column info from the source system"""
     orm_datasource = ConnectorRegistry.get_datasource(
         datasource_type, datasource_id, db.session)
     return self.json_response(orm_datasource.external_metadata())