[incubator-superset] branch master updated: part1 (#4641)

2018-03-19 Thread maximebeauchemin
This is an automated email from the ASF dual-hosted git repository.

maximebeauchemin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-superset.git


The following commit(s) were added to refs/heads/master by this push:
 new e9b5b1a  part1 (#4641)
e9b5b1a is described below

commit e9b5b1a305f81baff7e2a95ad8c643751bbf1cc0
Author: Hugh A. Miles II 
AuthorDate: Mon Mar 19 11:02:03 2018 -0700

part1 (#4641)
---
 .../assets/javascripts/explore/components/ExploreChartHeader.jsx  | 4 ++--
 superset/assets/javascripts/explore/components/SaveModal.jsx  | 8 
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git 
a/superset/assets/javascripts/explore/components/ExploreChartHeader.jsx 
b/superset/assets/javascripts/explore/components/ExploreChartHeader.jsx
index 00231df..69871dc 100644
--- a/superset/assets/javascripts/explore/components/ExploreChartHeader.jsx
+++ b/superset/assets/javascripts/explore/components/ExploreChartHeader.jsx
@@ -49,7 +49,7 @@ class ExploreChartHeader extends React.PureComponent {
   this.props.actions.createNewSlice(
 data.can_add, data.can_download, data.can_overwrite,
 data.slice, data.form_data);
-  this.props.addHistory({ isReplace: true, title: `[slice] 
${data.slice.slice_name}` });
+  this.props.addHistory({ isReplace: true, title: `[chart] 
${data.slice.slice_name}` });
 } else {
   this.props.actions.updateChartTitle(newTitle);
 }
@@ -97,7 +97,7 @@ class ExploreChartHeader extends React.PureComponent {
 
   
 
 
   
-{t('Save A Slice')}
+{t('Save A Chart')}
   
 
 
@@ -150,7 +150,7 @@ class SaveModal extends React.Component {
   checked={this.state.action === 'overwrite'}
   onChange={this.changeAction.bind(this, 'overwrite')}
 >
-  {t('Overwrite slice %s', this.props.slice.slice_name)}
+  {t('Overwrite chart %s', this.props.slice.slice_name)}
 
   }
 
@@ -163,7 +163,7 @@ class SaveModal extends React.Component {
   
   
@@ -184,7 +184,7 @@ class SaveModal extends React.Component {
 checked={this.state.addToDash === 'existing'}
 onChange={this.changeDash.bind(this, 'existing')}
   >
-{t('Add slice to existing dashboard')}
+{t('Add chart to existing dashboard')}
   
   

[incubator-superset] branch master updated: [cosmetic] removing table border in ModelView list (#4638)

2018-03-19 Thread maximebeauchemin
This is an automated email from the ASF dual-hosted git repository.

maximebeauchemin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-superset.git


The following commit(s) were added to refs/heads/master by this push:
 new 83f8f98  [cosmetic] removing table border in ModelView list (#4638)
83f8f98 is described below

commit 83f8f98ae3e472bfb3d9d9f6016c2c3719d1186f
Author: Maxime Beauchemin 
AuthorDate: Mon Mar 19 11:02:40 2018 -0700

[cosmetic] removing table border in ModelView list (#4638)
---
 superset/templates/superset/fab_overrides/list.html | 6 ++
 superset/views/base.py  | 5 +
 2 files changed, 11 insertions(+)

diff --git a/superset/templates/superset/fab_overrides/list.html 
b/superset/templates/superset/fab_overrides/list.html
new file mode 100644
index 000..6584590
--- /dev/null
+++ b/superset/templates/superset/fab_overrides/list.html
@@ -0,0 +1,6 @@
+{% extends 'appbuilder/general/widgets/list.html' %}
+
+{% block begin_content scoped %}
+
+
+{% endblock %}
diff --git a/superset/views/base.py b/superset/views/base.py
index 9ff883f..54a98c2 100644
--- a/superset/views/base.py
+++ b/superset/views/base.py
@@ -220,8 +220,13 @@ class BaseSupersetView(BaseView):
 }
 
 
+class SupersetListWidget(ListWidget):
+template = 'superset/fab_overrides/list.html'
+
+
 class SupersetModelView(ModelView):
 page_size = 100
+list_widget = SupersetListWidget
 
 
 class ListWidgetWithCheckboxes(ListWidget):

-- 
To stop receiving notification emails like this one, please contact
maximebeauche...@apache.org.


[incubator-superset] branch master updated: Only show overlay if container is set (#4601)

2018-03-19 Thread maximebeauchemin
This is an automated email from the ASF dual-hosted git repository.

maximebeauchemin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-superset.git


The following commit(s) were added to refs/heads/master by this push:
 new ba9379b  Only show overlay if container is set (#4601)
ba9379b is described below

commit ba9379b9491d38afe4172b9abd98d3818601ec3c
Author: Beto Dealmeida 
AuthorDate: Mon Mar 19 11:23:19 2018 -0700

Only show overlay if container is set (#4601)

* Pass width in props

* Only load overlay if container is set
---
 superset/assets/javascripts/chart/Chart.jsx | 1 +
 1 file changed, 1 insertion(+)

diff --git a/superset/assets/javascripts/chart/Chart.jsx 
b/superset/assets/javascripts/chart/Chart.jsx
index 54736e5..4b44106 100644
--- a/superset/assets/javascripts/chart/Chart.jsx
+++ b/superset/assets/javascripts/chart/Chart.jsx
@@ -223,6 +223,7 @@ class Chart extends React.PureComponent {
   !this.props.chartAlert &&
   this.props.refreshOverlayVisible &&
   !this.props.errorMessage &&
+  this.container &&
   

[incubator-superset] branch master updated: Fix sqllab numpy array (#4629)

2018-03-19 Thread johnbodley
This is an automated email from the ASF dual-hosted git repository.

johnbodley pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-superset.git


The following commit(s) were added to refs/heads/master by this push:
 new 5c98f56  Fix sqllab numpy array (#4629)
5c98f56 is described below

commit 5c98f5642b0928f0f496e957b584d97d1d3e7385
Author: michellethomas 
AuthorDate: Mon Mar 19 11:43:04 2018 -0700

Fix sqllab numpy array (#4629)

* Fixing error with sqllab numpy array

* Adding tests for failing sqllab data type
---
 superset/sql_lab.py   |  2 +-
 tests/sqllab_tests.py | 12 ++--
 2 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/superset/sql_lab.py b/superset/sql_lab.py
index f98231e..12644fc 100644
--- a/superset/sql_lab.py
+++ b/superset/sql_lab.py
@@ -97,7 +97,7 @@ def convert_results_to_df(cursor_description, data):
 if data:
 first_row = data[0]
 has_dict_col = any([isinstance(c, dict) for c in first_row])
-df_data = list(data) if has_dict_col else np.array(data)
+df_data = list(data) if has_dict_col else np.array(data, dtype=object)
 else:
 df_data = []
 
diff --git a/tests/sqllab_tests.py b/tests/sqllab_tests.py
index 01b10b2..977bbe0 100644
--- a/tests/sqllab_tests.py
+++ b/tests/sqllab_tests.py
@@ -203,8 +203,16 @@ class SqlLabTests(SupersetTestCase):
 raise_on_error=True)
 
 def test_df_conversion_no_dict(self):
-cols = [['string_col'], ['int_col']]
-data = [['a', 4]]
+cols = [['string_col'], ['int_col'], ['float_col']]
+data = [['a', 4, 4.0]]
+cdf = convert_results_to_df(cols, data)
+
+self.assertEquals(len(data), cdf.size)
+self.assertEquals(len(cols), len(cdf.columns))
+
+def test_df_conversion_tuple(self):
+cols = [['string_col'], ['int_col'], ['list_col'], ['float_col']]
+data = [(u'Text', 111, [123], 1.0)]
 cdf = convert_results_to_df(cols, data)
 
 self.assertEquals(len(data), cdf.size)

-- 
To stop receiving notification emails like this one, please contact
johnbod...@apache.org.


[incubator-superset] branch master updated: Use 'count' as the default metric when available (#4606)

2018-03-19 Thread maximebeauchemin
This is an automated email from the ASF dual-hosted git repository.

maximebeauchemin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-superset.git


The following commit(s) were added to refs/heads/master by this push:
 new ed9867c  Use 'count' as the default metric when available (#4606)
ed9867c is described below

commit ed9867c0cc210de81950053fd4827a9a4d25f7e2
Author: Maxime Beauchemin 
AuthorDate: Mon Mar 19 21:51:51 2018 -0700

Use 'count' as the default metric when available (#4606)

* Use 'count' as the default metric when available

Count is a much better default than the current behavior which is to use
whatever the first metric in the list happens to be.

* Addressing nits
---
 .../assets/javascripts/explore/stores/controls.jsx | 14 ---
 superset/assets/javascripts/modules/utils.js   | 16 +
 .../assets/spec/javascripts/modules/utils_spec.jsx | 28 ++
 3 files changed, 55 insertions(+), 3 deletions(-)

diff --git a/superset/assets/javascripts/explore/stores/controls.jsx 
b/superset/assets/javascripts/explore/stores/controls.jsx
index cc35d0e..617c717 100644
--- a/superset/assets/javascripts/explore/stores/controls.jsx
+++ b/superset/assets/javascripts/explore/stores/controls.jsx
@@ -1,5 +1,9 @@
 import React from 'react';
-import { formatSelectOptionsForRange, formatSelectOptions } from 
'../../modules/utils';
+import {
+  formatSelectOptionsForRange,
+  formatSelectOptions,
+  mainMetric,
+} from '../../modules/utils';
 import * as v from '../validators';
 import { colorPrimary, ALL_COLOR_SCHEMES, spectrums } from 
'../../modules/colors';
 import { defaultViewport } from '../../modules/geo';
@@ -82,6 +86,7 @@ const jsFunctionInfo = (
 .
   
 );
+
 function jsFunctionControl(label, description, extraDescr = null, height = 
100, defaultText = '') {
   return {
 type: 'TextAreaControl',
@@ -131,7 +136,10 @@ export const controls = {
 valueKey: 'metric_name',
 optionRenderer: m => ,
 valueRenderer: m => ,
-default: c => c.options && c.options.length > 0 ? 
[c.options[0].metric_name] : null,
+default: (c) => {
+  const metric = mainMetric(c.options);
+  return metric ? [metric] : null;
+},
 mapStateToProps: state => ({
   options: (state.datasource) ? state.datasource.metrics : [],
 }),
@@ -218,7 +226,7 @@ export const controls = {
 validators: [v.nonEmpty],
 optionRenderer: m => ,
 valueRenderer: m => ,
-default: c => c.options && c.options.length > 0 ? c.options[0].metric_name 
: null,
+default: c => mainMetric(c.options),
 valueKey: 'metric_name',
 mapStateToProps: state => ({
   options: (state.datasource) ? state.datasource.metrics : [],
diff --git a/superset/assets/javascripts/modules/utils.js 
b/superset/assets/javascripts/modules/utils.js
index b5590f0..6180783 100644
--- a/superset/assets/javascripts/modules/utils.js
+++ b/superset/assets/javascripts/modules/utils.js
@@ -259,3 +259,19 @@ export function getParam(name) {
   const results = regex.exec(location.search);
   return results === null ? '' : decodeURIComponent(results[1].replace(/\+/g, 
' '));
 }
+
+export function mainMetric(metricOptions) {
+  // Using 'count' as default metric if it exists, otherwise using whatever 
one shows up first
+  let metric;
+  if (metricOptions && metricOptions.length > 0) {
+metricOptions.forEach((m) => {
+  if (m.metric_name === 'count') {
+metric = 'count';
+  }
+});
+if (!metric) {
+  metric = metricOptions[0].metric_name;
+}
+  }
+  return metric;
+}
diff --git a/superset/assets/spec/javascripts/modules/utils_spec.jsx 
b/superset/assets/spec/javascripts/modules/utils_spec.jsx
index 174e0e1..309d62f 100644
--- a/superset/assets/spec/javascripts/modules/utils_spec.jsx
+++ b/superset/assets/spec/javascripts/modules/utils_spec.jsx
@@ -3,6 +3,7 @@ import { expect } from 'chai';
 import {
   tryNumify, slugify, formatSelectOptionsForRange, d3format,
   d3FormatPreset, d3TimeFormatPreset, defaultNumberFormatter,
+  mainMetric,
 } from '../../../javascripts/modules/utils';
 
 describe('utils', () => {
@@ -69,4 +70,31 @@ describe('utils', () => {
 expect(defaultNumberFormatter(-11100)).to.equal('-111M');
 expect(defaultNumberFormatter(-0.23)).to.equal('-230m');
   });
+  describe('mainMetric', () => {
+it('is null when no options', () => {
+  expect(mainMetric([])).to.equal(undefined);
+  expect(mainMetric(null)).to.equal(undefined);
+});
+it('prefers the "count" metric when first', () => {
+  const metrics = [
+{ metric_name: 'count' },
+{ metric_name: 'foo' },
+  ];
+  expect(mainMetric(metrics)).to.equal('count');
+});
+it('prefers the "count" metric when not first', () => {
+  const metrics = [
+{ metric_name: 'foo' },
+{ metric_name: 'count' },
+  ];
+  expect(mainMetric

[incubator-superset] branch master updated: Set filter_select_enabled default to True for Druid (#4608)

2018-03-19 Thread maximebeauchemin
This is an automated email from the ASF dual-hosted git repository.

maximebeauchemin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-superset.git


The following commit(s) were added to refs/heads/master by this push:
 new 1435840  Set filter_select_enabled default to True for Druid (#4608)
1435840 is described below

commit 1435840e3854a87b25c1069d5bbeaad84db7ca17
Author: Maxime Beauchemin 
AuthorDate: Mon Mar 19 22:15:43 2018 -0700

Set filter_select_enabled default to True for Druid (#4608)
---
 superset/connectors/druid/models.py | 1 +
 1 file changed, 1 insertion(+)

diff --git a/superset/connectors/druid/models.py 
b/superset/connectors/druid/models.py
index ef081a7..74eb575 100644
--- a/superset/connectors/druid/models.py
+++ b/superset/connectors/druid/models.py
@@ -456,6 +456,7 @@ class DruidDatasource(Model, BaseDatasource):
 # Columns
 datasource_name = Column(String(255))
 is_hidden = Column(Boolean, default=False)
+filter_select_enabled = Column(Boolean, default=True)  # override default
 fetch_values_from = Column(String(100))
 cluster_name = Column(
 String(250), ForeignKey('clusters.cluster_name'))

-- 
To stop receiving notification emails like this one, please contact
maximebeauche...@apache.org.


[incubator-superset] branch master updated: [examples] let's not use 'date' as a col name (#4555)

2018-03-19 Thread maximebeauchemin
This is an automated email from the ASF dual-hosted git repository.

maximebeauchemin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-superset.git


The following commit(s) were added to refs/heads/master by this push:
 new 8942436  [examples] let's not use 'date' as a col name (#4555)
8942436 is described below

commit 8942436ece4d0a63bbababa266a24e8632b267fc
Author: Maxime Beauchemin 
AuthorDate: Mon Mar 19 22:15:19 2018 -0700

[examples] let's not use 'date' as a col name (#4555)

'date' is a reserved word in most database
---
 superset/data/__init__.py | 24 
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/superset/data/__init__.py b/superset/data/__init__.py
index ceaaf43..ec87994 100644
--- a/superset/data/__init__.py
+++ b/superset/data/__init__.py
@@ -847,7 +847,7 @@ def load_unicode_test_data():
 df = pd.read_csv(os.path.join(DATA_FOLDER, 'unicode_utf8_unixnl_test.csv'),
  encoding="utf-8")
 # generate date/numeric data
-df['date'] = datetime.datetime.now().date()
+df['dttm'] = datetime.datetime.now().date()
 df['value'] = [random.randint(1, 100) for _ in range(len(df))]
 df.to_sql(  # pylint: disable=no-member
 'unicode_test',
@@ -858,7 +858,7 @@ def load_unicode_test_data():
 'phrase': String(500),
 'short_phrase': String(10),
 'with_missing': String(100),
-'date': Date(),
+'dttm': Date(),
 'value': Float(),
 },
 index=False)
@@ -869,7 +869,7 @@ def load_unicode_test_data():
 obj = db.session.query(TBL).filter_by(table_name='unicode_test').first()
 if not obj:
 obj = TBL(table_name='unicode_test')
-obj.main_dttm_col = 'date'
+obj.main_dttm_col = 'dttm'
 obj.database = get_or_create_main_db()
 db.session.merge(obj)
 db.session.commit()
@@ -877,7 +877,7 @@ def load_unicode_test_data():
 tbl = obj
 
 slice_data = {
-"granularity": "date",
+"granularity": "dttm",
 "groupby": [],
 "metric": 'sum__value',
 "row_limit": config.get("ROW_LIMIT"),
@@ -981,7 +981,7 @@ def load_country_map_data():
 """Loading data for map with country map"""
 csv_path = os.path.join(DATA_FOLDER, 
'birth_france_data_for_country_map.csv')
 data = pd.read_csv(csv_path, encoding="utf-8")
-data['date'] = datetime.datetime.now().date()
+data['dttm'] = datetime.datetime.now().date()
 data.to_sql(  # pylint: disable=no-member
 'birth_france_by_region',
 db.engine,
@@ -1001,7 +1001,7 @@ def load_country_map_data():
 '2012': BigInteger,
 '2013': BigInteger,
 '2014': BigInteger,
-'date': Date(),
+'dttm': Date(),
 },
 index=False)
 print("Done loading table!")
@@ -1010,7 +1010,7 @@ def load_country_map_data():
 obj = 
db.session.query(TBL).filter_by(table_name='birth_france_by_region').first()
 if not obj:
 obj = TBL(table_name='birth_france_by_region')
-obj.main_dttm_col = 'date'
+obj.main_dttm_col = 'dttm'
 obj.database = get_or_create_main_db()
 db.session.merge(obj)
 db.session.commit()
@@ -1292,7 +1292,7 @@ def load_deck_dash():
 },
 "datasource": "5__table",
 "filters": [],
-"granularity_sqla": "date",
+"granularity_sqla": "dttm",
 "groupby": [],
 "having": "",
 "mapbox_style": "mapbox://styles/mapbox/light-v9",
@@ -1336,7 +1336,7 @@ def load_deck_dash():
 "latCol": "LAT",
 },
 "mapbox_style": "mapbox://styles/mapbox/dark-v9",
-"granularity_sqla": "date",
+"granularity_sqla": "dttm",
 "size": "count",
 "viz_type": "deck_screengrid",
 "since": None,
@@ -1383,7 +1383,7 @@ def load_deck_dash():
 "filters": [],
 "row_limit": 5000,
 "mapbox_style": "mapbox://styles/mapbox/streets-v9",
-"granularity_sqla": "date",
+"granularity_sqla": "dttm",
 "size": "count",
 "viz_type": "deck_hex",
 "since": None,
@@ -1432,7 +1432,7 @@ def load_deck_dash():
 "filters": [],
 "row_limit": 5000,
 "mapbox_style": "mapbox://styles/mapbox/satellite-streets-v9",
-"granularity_sqla": "date",
+"granularity_sqla": "dttm",
 "size": "count",
 "viz_type": "deck_grid",
 "since": None,
@@ -1547,7 +1547,7 @@ def load_deck_dash():
 "datasource": "10__table",
 "viz_type": "deck_arc",
 "slice_id": 42,
-"granularity_sqla": "date",
+"granularity_sqla": "dttm",
 "time_grain_sqla": "Time Column",
 "since": None,
 "until": None,

-- 
To stop receiving notification emails like this one, please contact
maximebeauche...@apache.org.


[incubator-superset] branch master updated: [sql lab] search to use fist&last name instead of username (#4628)

2018-03-19 Thread maximebeauchemin
This is an automated email from the ASF dual-hosted git repository.

maximebeauchemin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-superset.git


The following commit(s) were added to refs/heads/master by this push:
 new fc47729  [sql lab] search to use fist&last name instead of username 
(#4628)
fc47729 is described below

commit fc47729233e7ce44e225edbeb628f6a5f0376eda
Author: Maxime Beauchemin 
AuthorDate: Mon Mar 19 22:16:17 2018 -0700

[sql lab] search to use fist&last name instead of username (#4628)

In our environment username are not readable coming out of oauth, so
we'd rather use first&last when available.
---
 .../javascripts/SqlLab/components/QuerySearch.jsx  | 39 --
 superset/models/sql_lab.py |  4 +--
 superset/utils.py  |  9 +
 3 files changed, 39 insertions(+), 13 deletions(-)

diff --git a/superset/assets/javascripts/SqlLab/components/QuerySearch.jsx 
b/superset/assets/javascripts/SqlLab/components/QuerySearch.jsx
index 10c1c88..a3e4bf4 100644
--- a/superset/assets/javascripts/SqlLab/components/QuerySearch.jsx
+++ b/superset/assets/javascripts/SqlLab/components/QuerySearch.jsx
@@ -31,6 +31,17 @@ class QuerySearch extends React.PureComponent {
   queriesArray: [],
   queriesLoading: true,
 };
+this.userMutator = this.userMutator.bind(this);
+this.changeUser = this.changeUser.bind(this);
+this.dbMutator = this.dbMutator.bind(this);
+this.onChange = this.onChange.bind(this);
+this.changeSearch = this.changeSearch.bind(this);
+this.changeFrom = this.changeFrom.bind(this);
+this.changeTo = this.changeTo.bind(this);
+this.changeStatus = this.changeStatus.bind(this);
+this.refreshQueries = this.refreshQueries.bind(this);
+this.onUserClicked = this.onUserClicked.bind(this);
+this.onDbClicked = this.onDbClicked.bind(this);
   }
   componentDidMount() {
 this.refreshQueries();
@@ -90,10 +101,16 @@ class QuerySearch extends React.PureComponent {
   changeSearch(event) {
 this.setState({ searchText: event.target.value });
   }
+  userLabel(user) {
+if (user.first_name && user.last_name) {
+  return user.first_name + ' ' + user.last_name;
+}
+return user.username;
+  }
   userMutator(data) {
 const options = [];
 for (let i = 0; i < data.pks.length; i++) {
-  options.push({ value: data.pks[i], label: data.result[i].username });
+  options.push({ value: data.pks[i], label: this.userLabel(data.result[i]) 
});
 }
 return options;
   }
@@ -135,21 +152,21 @@ class QuerySearch extends React.PureComponent {
   dataEndpoint="/users/api/read"
   mutator={this.userMutator}
   value={this.state.userId}
-  onChange={this.changeUser.bind(this)}
+  onChange={this.changeUser}
 />
   
   
 
   
   
 
@@ -162,7 +179,7 @@ class QuerySearch extends React.PureComponent {
 .slice(1, TIME_OPTIONS.length).map(xt => ({ value: xt, label: 
xt }))}
   value={this.state.from}
   autosize={false}
-  onChange={this.changeFrom.bind(this)}
+  onChange={this.changeFrom}
 />
 
  ({ value: xt, label: xt }))}
   value={this.state.to}
   autosize={false}
-  onChange={this.changeTo.bind(this)}
+  onChange={this.changeTo}
 />
 
 
 
-
+
   {t('Search')}
 
   
@@ -203,8 +220,8 @@ class QuerySearch extends React.PureComponent {
 'state', 'db', 'user', 'time',
 'progress', 'rows', 'sql', 'querylink',
   ]}
-  onUserClicked={this.onUserClicked.bind(this)}
-  onDbClicked={this.onDbClicked.bind(this)}
+  onUserClicked={this.onUserClicked}
+  onDbClicked={this.onDbClicked}
   queries={this.state.queriesArray}
   actions={this.props.actions}
 />
diff --git a/superset/models/sql_lab.py b/superset/models/sql_lab.py
index bf37db7..81ee41a 100644
--- a/superset/models/sql_lab.py
+++ b/superset/models/sql_lab.py
@@ -19,7 +19,7 @@ from sqlalchemy.orm import backref, relationship
 
 from superset import sm
 from superset.models.helpers import AuditMixinNullable
-from superset.utils import QueryStatus
+from superset.utils import QueryStatus, user_label
 
 install_aliases()
 
@@ -109,7 +109,7 @@ class Query(Model):
 'tab': self.tab_name,
 'tempTable': self.tmp_table_name,
 'userId': self.user_id,
-'user': self.user.username,
+'user': user_label(self.user),
 'limit_reached': self.limit_reached,
 'resultsKey': self.results_key,