class SqlMetricInlineView(CompactCRUDMixin, RookModelView): # noqa datamodel = SQLAInterface(models.SqlMetric) list_title = _('List Metrics') show_title = _('Show Metric') add_title = _('Add Metric') edit_title = _('Edit Metric') list_columns = ['metric_name', 'verbose_name', 'metric_type'] edit_columns = [ 'metric_name', 'description', 'verbose_name', 'metric_type', 'expression', 'table', 'd3format', 'is_restricted', 'warning_text' ] description_columns = { 'expression': utils.markdown( 'a valid SQL expression as supported by the underlying backend. ' 'Example: `count(DISTINCT userid)`', True), 'is_restricted': _('Whether the access to this metric is restricted ' 'to certain roles. Only roles with the permission ' "'metric access on XXX (the name of this metric)' " 'are allowed to access this metric'), 'd3format': utils.markdown( 'd3 formatting string as defined [here]' '(https://github.com/d3/d3-format/blob/master/README.md#format). ' 'For instance, this default formatting applies in the Table ' 'visualization and allow for different metric to use different ' 'formats', True, ), } add_columns = edit_columns page_size = 500 label_columns = { 'metric_name': _('Metric'), 'description': _('Description'), 'verbose_name': _('Verbose Name'), 'metric_type': _('Type'), 'expression': _('SQL Expression'), 'table': _('Table'), 'd3format': _('D3 Format'), 'is_restricted': _('Is Restricted'), 'warning_text': _('Warning Message'), } def post_add(self, metric): if metric.is_restricted: security.merge_perm(sm, 'metric_access', metric.get_perm()) def post_update(self, metric): if metric.is_restricted: security.merge_perm(sm, 'metric_access', metric.get_perm())
class DruidMetricInlineView(CompactCRUDMixin, RookModelView): # noqa datamodel = SQLAInterface(models.DruidMetric) list_title = _('List Druid Metric') show_title = _('Show Druid Metric') add_title = _('Add Druid Metric') edit_title = _('Edit Druid Metric') list_columns = ['metric_name', 'verbose_name', 'metric_type'] edit_columns = [ 'metric_name', 'description', 'verbose_name', 'metric_type', 'json', 'datasource', 'd3format', 'is_restricted', 'warning_text' ] add_columns = edit_columns page_size = 500 validators_columns = { 'json': [validate_json], } description_columns = { 'metric_type': utils.markdown( 'use `postagg` as the metric type if you are defining a ' '[Druid Post Aggregation]' '(http://druid.io/docs/latest/querying/post-aggregations.html)', True), 'is_restricted': _('Whether the access to this metric is restricted ' 'to certain roles. Only roles with the permission ' "'metric access on XXX (the name of this metric)' " 'are allowed to access this metric'), } label_columns = { 'metric_name': _('Metric'), 'description': _('Description'), 'verbose_name': _('Verbose Name'), 'metric_type': _('Type'), 'json': _('JSON'), 'datasource': _('Druid Datasource'), 'warning_text': _('Warning Message'), } def post_add(self, metric): if metric.is_restricted: security.merge_perm(sm, 'metric_access', metric.get_perm()) def post_update(self, metric): if metric.is_restricted: security.merge_perm(sm, 'metric_access', metric.get_perm())
class DruidColumnInlineView(CompactCRUDMixin, RookModelView): # noqa datamodel = SQLAInterface(models.DruidColumn) list_title = _('List Druid Column') show_title = _('Show Druid Column') add_title = _('Add Druid Column') edit_title = _('Edit Druid Column') list_widget = ListWidgetWithCheckboxes edit_columns = [ 'column_name', 'description', 'dimension_spec_json', 'datasource', 'groupby', 'filterable', 'count_distinct', 'sum', 'min', 'max' ] add_columns = edit_columns list_columns = [ 'column_name', 'verbose_name', 'type', 'groupby', 'filterable', 'count_distinct', 'sum', 'min', 'max' ] can_delete = False page_size = 500 label_columns = { 'column_name': _('Column'), 'type': _('Type'), 'datasource': _('Datasource'), 'groupby': _('Groupable'), 'filterable': _('Filterable'), 'count_distinct': _('Count Distinct'), 'sum': _('Sum'), 'min': _('Min'), 'max': _('Max'), } description_columns = { 'filterable': _('Whether this column is exposed in the `Filters` section ' 'of the explore view.'), 'dimension_spec_json': utils.markdown( 'this field can be used to specify ' 'a `dimensionSpec` as documented [here]' '(http://druid.io/docs/latest/querying/dimensionspecs.html). ' 'Make sure to input valid JSON and that the ' '`outputName` matches the `column_name` defined ' 'above.', True), } def pre_update(self, col): # If a dimension spec JSON is given, ensure that it is # valid JSON and that `outputName` is specified if col.dimension_spec_json: try: dimension_spec = json.loads(col.dimension_spec_json) except ValueError as e: raise ValueError('Invalid Dimension Spec JSON: ' + str(e)) if not isinstance(dimension_spec, dict): raise ValueError('Dimension Spec must be a JSON object') if 'outputName' not in dimension_spec: raise ValueError( 'Dimension Spec does not contain `outputName`') if 'dimension' not in dimension_spec: raise ValueError('Dimension Spec is missing `dimension`') # `outputName` should be the same as the `column_name` if dimension_spec['outputName'] != col.column_name: raise ValueError( '`outputName` [{}] unequal to `column_name` [{}]'.format( dimension_spec['outputName'], col.column_name)) def post_update(self, col): col.generate_metrics() def post_add(self, col): self.post_update(col)
def description_markeddown(self): return utils.markdown(self.description)
class TableColumnInlineView(CompactCRUDMixin, RookModelView): # noqa datamodel = SQLAInterface(models.TableColumn) list_title = _('List Columns') show_title = _('Show Column') add_title = _('Add Column') edit_title = _('Edit Column') can_delete = False list_widget = ListWidgetWithCheckboxes edit_columns = [ 'column_name', 'verbose_name', 'description', 'type', 'groupby', 'filterable', 'table', 'count_distinct', 'sum', 'min', 'max', 'expression', 'is_dttm', 'python_date_format', 'database_expression' ] add_columns = edit_columns list_columns = [ 'column_name', 'verbose_name', 'type', 'groupby', 'filterable', 'count_distinct', 'sum', 'min', 'max', 'is_dttm' ] page_size = 500 description_columns = { 'is_dttm': _('Whether to make this column available as a ' '[Time Granularity] option, column has to be DATETIME or ' 'DATETIME-like'), 'filterable': _('Whether this column is exposed in the `Filters` section ' 'of the explore view.'), 'type': _('The data type that was inferred by the database. ' 'It may be necessary to input a type manually for ' 'expression-defined columns in some cases. In most case ' 'users should not need to alter this.'), 'expression': utils.markdown( 'a valid SQL expression as supported by the underlying backend. ' 'Example: `substr(name, 1, 1)`', True), 'python_date_format': utils.markdown( Markup( 'The pattern of timestamp format, use ' '<a href="https://docs.python.org/2/library/' 'datetime.html#strftime-strptime-behavior">' 'python datetime string pattern</a> ' 'expression. If time is stored in epoch ' 'format, put `epoch_s` or `epoch_ms`. Leave `Database Expression` ' 'below empty if timestamp is stored in ' 'String or Integer(epoch) type'), True), 'database_expression': utils.markdown( 'The database expression to cast internal datetime ' 'constants to database date/timestamp type according to the DBAPI. ' 'The expression should follow the pattern of ' '%Y-%m-%d %H:%M:%S, based on different DBAPI. ' 'The string should be a python string formatter \n' "`Ex: TO_DATE('{}', 'YYYY-MM-DD HH24:MI:SS')` for Oracle " 'Rook uses default expression based on DB URI if this ' 'field is blank.', True), } label_columns = { 'column_name': _('Column'), 'verbose_name': _('Verbose Name'), 'description': _('Description'), 'groupby': _('Groupable'), 'filterable': _('Filterable'), 'table': _('Table'), 'count_distinct': _('Count Distinct'), 'sum': _('Sum'), 'min': _('Min'), 'max': _('Max'), 'expression': _('Expression'), 'is_dttm': _('Is temporal'), 'python_date_format': _('Datetime Format'), 'database_expression': _('Database Expression'), 'type': _('Type'), }