From 98ba32399e6fa58f45b4486e0535b8916eab51ce Mon Sep 17 00:00:00 2001 From: Maxime Beauchemin Date: Wed, 3 Feb 2016 23:09:52 -0800 Subject: [PATCH] Polish --- panoramix/models.py | 9 +++++ panoramix/static/panoramix.js | 7 ++-- panoramix/templates/panoramix/sql.html | 8 ++--- panoramix/views.py | 47 ++++++++++++++++++-------- 4 files changed, 50 insertions(+), 21 deletions(-) diff --git a/panoramix/models.py b/panoramix/models.py index 1a5b074c5f97e..12ed8b91b81df 100644 --- a/panoramix/models.py +++ b/panoramix/models.py @@ -263,6 +263,15 @@ def get_table(self, table_name): autoload=True, autoload_with=self.get_sqla_engine()) + def get_columns(self, table_name): + + from sqlalchemy import create_engine + from sqlalchemy.engine import reflection + + engine = self.get_sqla_engine() + insp = reflection.Inspector.from_engine(engine) + return insp.get_columns(table_name) + @property def sqlalchemy_uri_decrypted(self): conn = sqla.engine.url.make_url(self.sqlalchemy_uri) diff --git a/panoramix/static/panoramix.js b/panoramix/static/panoramix.js index b42654da48ff8..53a2608e58467 100644 --- a/panoramix/static/panoramix.js +++ b/panoramix/static/panoramix.js @@ -444,8 +444,10 @@ var px = (function() { } function initSqlEditorView() { + var database_id = $('#database_id').val(); var editor = ace.edit("sql"); editor.$blockScrolling = Infinity + editor.getSession().setUseWrapMode(true); var textarea = $('#sql').hide(); editor.setTheme("ace/theme/crimson_editor"); @@ -457,14 +459,15 @@ var px = (function() { editor.focus(); $("select").select2({dropdownAutoWidth : true}); function showTableMetadata() { - $(".metadata").load('/panoramix/table/' + $("#dbtable").val() + '/'); + $(".metadata").load( + '/panoramix/table/' + database_id + '/' + $("#dbtable").val() + '/'); } $("#dbtable").on("change", showTableMetadata); showTableMetadata(); $("#create_view").click(function(){alert("Not implemented");}); $(".sqlcontent").show(); $("#select_star").click(function(){ - $.ajax('/panoramix/select_star/' + $("#dbtable").val() + '/') + $.ajax('/panoramix/select_star/' + database_id + '/' + $("#dbtable").val() + '/') .done(function(msg){ editor.setValue(msg); }); diff --git a/panoramix/templates/panoramix/sql.html b/panoramix/templates/panoramix/sql.html index 84c38e73ed464..67c77958f1d51 100644 --- a/panoramix/templates/panoramix/sql.html +++ b/panoramix/templates/panoramix/sql.html @@ -60,10 +60,10 @@

db: [{{ db }}]

diff --git a/panoramix/views.py b/panoramix/views.py index bf174e845dc2b..d38dec68443ae 100644 --- a/panoramix/views.py +++ b/panoramix/views.py @@ -13,6 +13,9 @@ from sqlalchemy import create_engine import sqlalchemy as sqla from wtforms.validators import ValidationError +import pandas as pd +from sqlalchemy import select, text +from sqlalchemy.sql.expression import TextAsFrom from panoramix import appbuilder, db, models, viz, utils, app, sm, ascii_art @@ -558,33 +561,49 @@ def dashboard(self, identifier): @expose("/sql//") @utils.log_this def sql(self, database_id): - mydb = db.session.query(models.Database).filter_by(id=database_id).first() + mydb = db.session.query( + models.Database).filter_by(id=database_id).first() + engine = mydb.get_sqla_engine() + tables = engine.table_names() return self.render_template( "panoramix/sql.html", database_id=database_id, table_id=request.args.get('table_id'), + tables=tables, db=mydb) @has_access - @expose("/table//") + @expose("/table///") @utils.log_this - def table(self, table_id): - t = db.session.query(models.SqlaTable).filter_by(id=table_id).first() + def table(self, database_id, table_name): + mydb = db.session.query( + models.Database).filter_by(id=database_id).first() + cols = mydb.get_columns(table_name) + df = pd.DataFrame([(c['name'], c['type']) for c in cols]) + df.columns = ['col', 'type'] return self.render_template( "panoramix/ajah.html", - content=t.html) + content=df.to_html( + index=False, + na_rep='', + classes=( + "dataframe table table-striped table-bordered " + "table-condensed sql_results"))) @has_access - @expose("/select_star//") + @expose("/select_star///") @utils.log_this - def select_star(self, table_id): - t = db.session.query(models.SqlaTable).filter_by(id=table_id).first() + def select_star(self, database_id, table_name): + mydb = db.session.query( + models.Database).filter_by(id=database_id).first() + t = mydb.get_table(table_name) fields = ", ".join( - [c.column_name for c in t.columns if not c.expression] or "*") - s = "SELECT\n{fields}\nFROM {t.table_name}".format(**locals()) + [c.name for c in t.get_columns()] or "*") + s = "SELECT\n{fields}\nFROM {table_name}".format(**locals()) return self.render_template( "panoramix/ajah.html", - content=s) + content=s + ) @has_access @expose("/runsql/", methods=['POST', 'GET']) @@ -598,9 +617,6 @@ def runsql(self): mydb = session.query(models.Database).filter_by(id=database_id).first() content = "" if mydb: - from pandas import read_sql_query - from sqlalchemy import select, text - from sqlalchemy.sql.expression import TextAsFrom eng = mydb.get_sqla_engine() if limit: sql = sql.strip().strip(';') @@ -611,9 +627,10 @@ def runsql(self): ) sql= str(qry.compile(eng, compile_kwargs={"literal_binds": True})) try: - df = read_sql_query(sql=sql, con=eng) + df = pd.read_sql_query(sql=sql, con=eng) content = df.to_html( index=False, + na_rep='', classes=( "dataframe table table-striped table-bordered " "table-condensed sql_results"))