Final touches on getting decent database support
This commit is contained in:
parent
9e227494ca
commit
3321a56782
|
|
@ -41,6 +41,8 @@ class Database(Model, AuditMixin):
|
|||
database_name = Column(String(256), unique=True)
|
||||
sqlalchemy_uri = Column(String(1024))
|
||||
|
||||
baselink = "datasourcemodelview"
|
||||
|
||||
def __repr__(self):
|
||||
return self.database_name
|
||||
|
||||
|
|
@ -59,11 +61,16 @@ class Table(Model, Queryable, AuditMixin):
|
|||
__tablename__ = 'tables'
|
||||
id = Column(Integer, primary_key=True)
|
||||
table_name = Column(String(256), unique=True)
|
||||
main_datetime_column_id = Column(Integer, ForeignKey('table_columns.id'))
|
||||
main_datetime_column = relationship(
|
||||
'TableColumn', foreign_keys=[main_datetime_column_id])
|
||||
default_endpoint = Column(Text)
|
||||
database_id = Column(Integer, ForeignKey('dbs.id'))
|
||||
database = relationship(
|
||||
'Database', backref='tables', foreign_keys=[database_id])
|
||||
|
||||
baselink = "tableview"
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
return self.table_name
|
||||
|
|
@ -151,7 +158,7 @@ class Table(Model, Queryable, AuditMixin):
|
|||
"SELECT\n"
|
||||
" {select_exprs}\n"
|
||||
"FROM {self.table_name}\n"
|
||||
"{limiting_join}\n"
|
||||
"{limiting_join}"
|
||||
"WHERE\n"
|
||||
" {where_clause}\n"
|
||||
"GROUP BY\n"
|
||||
|
|
@ -221,6 +228,8 @@ class TableColumn(Model, AuditMixin):
|
|||
filterable = Column(Boolean, default=False)
|
||||
description = Column(Text, default='')
|
||||
|
||||
def __repr__(self):
|
||||
return self.column_name
|
||||
|
||||
class Cluster(Model, AuditMixin):
|
||||
__tablename__ = 'clusters'
|
||||
|
|
@ -350,6 +359,7 @@ class Datasource(Model, AuditMixin, Queryable):
|
|||
timeseries_limit=15, row_limit=None):
|
||||
qry_start_dttm = datetime.now()
|
||||
|
||||
query_str = ""
|
||||
aggregations = {
|
||||
m.metric_name: m.json_obj
|
||||
for m in self.metrics if m.metric_name in metrics
|
||||
|
|
@ -409,6 +419,7 @@ class Datasource(Model, AuditMixin, Queryable):
|
|||
}],
|
||||
}
|
||||
client.groupby(**pre_qry)
|
||||
query_str += json.dumps(client.query_dict, indent=2) + "\n"
|
||||
df = client.export_pandas()
|
||||
if not df is None and not df.empty:
|
||||
dims = qry['dimensions']
|
||||
|
|
@ -435,9 +446,12 @@ class Datasource(Model, AuditMixin, Queryable):
|
|||
qry['limit_spec'] = None
|
||||
|
||||
client.groupby(**qry)
|
||||
query_str += json.dumps(client.query_dict, indent=2)
|
||||
df = client.export_pandas()
|
||||
return QueryResult(
|
||||
df=df, query="", duration=datetime.now() - qry_start_dttm)
|
||||
df=df,
|
||||
query=query_str,
|
||||
duration=datetime.now() - qry_start_dttm)
|
||||
|
||||
|
||||
#class Metric(Model, AuditMixin):
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ form input.form-control {
|
|||
max-width: 350px;
|
||||
//width: 350px;
|
||||
}
|
||||
|
||||
</style>
|
||||
{% endblock %}
|
||||
{% block content_fluid %}
|
||||
|
|
@ -30,7 +31,7 @@ form input.form-control {
|
|||
{% if datasource.description %}
|
||||
<i class="fa fa-info-circle" data-toggle="tooltip" data-placement="bottom" title="{{ datasource.description }}"></i>
|
||||
{% endif %}
|
||||
<a href="/datasourcemodelview/edit/{{ datasource.id }}">
|
||||
<a href="/{{ datasource.baselink }}/edit/{{ datasource.id }}">
|
||||
<i class="fa fa-edit"></i>
|
||||
</a>
|
||||
</h3>
|
||||
|
|
@ -39,11 +40,20 @@ form input.form-control {
|
|||
<form id="query" method="GET" style="display: none;">
|
||||
<div>{{ form.viz_type.label }}: {{ form.viz_type(class_="form-control select2") }}</div>
|
||||
<div>{{ form.metrics.label }}: {{ form.metrics(class_="form-control select2") }}</div>
|
||||
<div>{{ form.granularity.label }}: {{ form.granularity(class_="form-control select2_free_granularity") }}</div>
|
||||
<div>{{ form.granularity.label }}
|
||||
<i class="fa fa-info-circle" data-toggle="tooltip" data-placement="right"
|
||||
title="Supports natural language time as in '10 seconds', '1 day' or '1 week'"
|
||||
id="blah"></i>
|
||||
{{ form.granularity(class_="form-control select2_free_granularity") }}</div>
|
||||
<div class="row">
|
||||
<div class="form-group">
|
||||
<div class="col-xs-6">{{ form.since.label }}: {{ form.since(class_="form-control select2_free_since") }}</div>
|
||||
<div class="col-xs-6">{{ form.until.label }}: {{ form.until(class_="form-control select2_free_until") }}</div>
|
||||
<div class="col-xs-6">{{ form.since.label }}
|
||||
<i class="fa fa-info-circle" data-toggle="tooltip" data-placement="right"
|
||||
title="Supports natural language time as in '1 day ago', '28 days' or '3 years'"
|
||||
id="blah"></i>
|
||||
{{ form.since(class_="form-control select2_free_since") }}</div>
|
||||
<div class="col-xs-6">{{ form.until.label }}
|
||||
{{ form.until(class_="form-control select2_free_until") }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>{{ form.groupby.label }}: {{ form.groupby(class_="form-control select2") }}</div>
|
||||
|
|
@ -70,16 +80,14 @@ form input.form-control {
|
|||
<button type="button" class="btn btn-primary" id="druidify">Druidify!</button>
|
||||
<button type="button" class="btn btn-default" id="bookmark">Bookmark</button>
|
||||
<hr style="margin-bottom: 0px;">
|
||||
<img src="{{ url_for("static", filename="panoramix.png") }}" width=250>
|
||||
<img src="{{ url_for("static", filename="tux_panoramix.png") }}" width=250>
|
||||
</form><br>
|
||||
</div>
|
||||
|
||||
<div class="col-md-9">
|
||||
<h3>{{ viz.verbose_name }}
|
||||
<span class="label label-success">{{ "{0:0.2f}".format(results.duration.total_seconds()) }} s</span>
|
||||
<span class="label label-info" data-html="true"
|
||||
title="<code><pre>{{ results.query }}</pre></code>"
|
||||
data-toggle="tooltip" data-placement="bottom" >query</span>
|
||||
<span class="label label-info btn" data-toggle="modal" data-target="#query_modal">query</span>
|
||||
</h3>
|
||||
<hr/>
|
||||
{% block viz %}
|
||||
|
|
@ -98,6 +106,22 @@ form input.form-control {
|
|||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal fade" id="query_modal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||
<h4 class="modal-title" id="myModalLabel">Query</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<pre>{{ results.query }}</pre>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block tail_js %}
|
||||
|
|
|
|||
|
|
@ -124,7 +124,7 @@ class TableView(ModelView, DeleteMixin):
|
|||
datamodel = SQLAInterface(models.Table)
|
||||
list_columns = ['table_link', 'database']
|
||||
add_columns = ['table_name', 'database', 'default_endpoint']
|
||||
edit_columns = add_columns
|
||||
edit_columns = ['table_name', 'database', 'main_datetime_column', 'default_endpoint']
|
||||
related_views = [TableColumnInlineView, SqlMetricInlineView]
|
||||
|
||||
def post_insert(self, table):
|
||||
|
|
|
|||
Loading…
Reference in New Issue