Add plot functionality to unsaved sql query and use htmx
This commit is contained in:
30
app.py
30
app.py
@@ -478,20 +478,8 @@ def sql_explorer():
|
|||||||
@app.route("/sql_query", methods=['POST'])
|
@app.route("/sql_query", methods=['POST'])
|
||||||
def sql_query():
|
def sql_query():
|
||||||
query = request.form.get('query')
|
query = request.form.get('query')
|
||||||
action = request.form.get('action')
|
|
||||||
title = request.form.get('title')
|
title = request.form.get('title')
|
||||||
|
|
||||||
if action == 'execute':
|
|
||||||
(results, columns, error) = db.sql_explorer.execute_sql(query)
|
|
||||||
saved_queries = db.sql_explorer.list_saved_queries()
|
|
||||||
return render_template('partials/sql_explorer/sql_query.html',
|
|
||||||
title=title,
|
|
||||||
query=query,
|
|
||||||
results=results,
|
|
||||||
columns=columns,
|
|
||||||
error=error,
|
|
||||||
saved_queries=saved_queries)
|
|
||||||
else:
|
|
||||||
error = db.sql_explorer.save_query(title, query)
|
error = db.sql_explorer.save_query(title, query)
|
||||||
saved_queries = db.sql_explorer.list_saved_queries()
|
saved_queries = db.sql_explorer.list_saved_queries()
|
||||||
return render_template('partials/sql_explorer/sql_query.html',
|
return render_template('partials/sql_explorer/sql_query.html',
|
||||||
@@ -500,6 +488,16 @@ def sql_query():
|
|||||||
error=error,
|
error=error,
|
||||||
saved_queries=saved_queries)
|
saved_queries=saved_queries)
|
||||||
|
|
||||||
|
@app.route("/sql_query/execute", methods=['POST'])
|
||||||
|
def execute_sql_query():
|
||||||
|
query = request.form.get('query')
|
||||||
|
|
||||||
|
(results, columns, error) = db.sql_explorer.execute_sql(query)
|
||||||
|
return render_template('partials/sql_explorer/results.html',
|
||||||
|
results=results,
|
||||||
|
columns=columns,
|
||||||
|
error=error)
|
||||||
|
|
||||||
@app.route('/load_sql_query/<int:query_id>', methods=['GET'])
|
@app.route('/load_sql_query/<int:query_id>', methods=['GET'])
|
||||||
def load_sql_query(query_id):
|
def load_sql_query(query_id):
|
||||||
(title, query) = db.sql_explorer.get_saved_query(query_id)
|
(title, query) = db.sql_explorer.get_saved_query(query_id)
|
||||||
@@ -533,6 +531,14 @@ def plot_query(query_id):
|
|||||||
plot_div = generate_plot(results_df, title)
|
plot_div = generate_plot(results_df, title)
|
||||||
return plot_div
|
return plot_div
|
||||||
|
|
||||||
|
@app.route("/plot/show", methods=['POST'])
|
||||||
|
def plot_unsaved_query(): # Rename?
|
||||||
|
query = request.form.get('query')
|
||||||
|
title = request.form.get('title')
|
||||||
|
results_df = db.read_sql_as_df(query)
|
||||||
|
plot_div = generate_plot(results_df, title)
|
||||||
|
return plot_div
|
||||||
|
|
||||||
def get_routes():
|
def get_routes():
|
||||||
routes = []
|
routes = []
|
||||||
for rule in app.url_map.iter_rules():
|
for rule in app.url_map.iter_rules():
|
||||||
|
|||||||
26
templates/partials/sql_explorer/results.html
Normal file
26
templates/partials/sql_explorer/results.html
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
{% if error %}
|
||||||
|
<div class="bg-red-200 text-red-800 p-3 rounded mb-4">
|
||||||
|
<strong>Error:</strong> {{ error }}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if results %}
|
||||||
|
<table class="min-w-full bg-white">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
{% for col in columns %}
|
||||||
|
<th class="py-2 px-4 border-b">{{ col }}</th>
|
||||||
|
{% endfor %}
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for row in results %}
|
||||||
|
<tr class="text-center">
|
||||||
|
{% for col in columns %}
|
||||||
|
<td class="py-2 px-4 border-b">{{ row[col] }}</td>
|
||||||
|
{% endfor %}
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
{% endif %}
|
||||||
@@ -26,7 +26,8 @@
|
|||||||
<!-- Buttons -->
|
<!-- Buttons -->
|
||||||
<div class="flex space-x-2 pt-1">
|
<div class="flex space-x-2 pt-1">
|
||||||
<!-- Execute Button -->
|
<!-- Execute Button -->
|
||||||
<button type="submit" name="action" value="execute"
|
<button hx-post="{{ url_for('execute_sql_query') }}" hx-target="#execute-query-results"
|
||||||
|
hx-include="[name='query']" hx-trigger="click" hx-swap="innerHTML"
|
||||||
class="flex items-center bg-blue-500 text-white px-4 py-2 rounded hover:bg-blue-600 focus:outline-none focus:ring-2 focus:ring-blue-500">
|
class="flex items-center bg-blue-500 text-white px-4 py-2 rounded hover:bg-blue-600 focus:outline-none focus:ring-2 focus:ring-blue-500">
|
||||||
<!-- Execute Icon (Heroicon: Play) -->
|
<!-- Execute Icon (Heroicon: Play) -->
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-2" fill="none" viewBox="0 0 24 24"
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-2" fill="none" viewBox="0 0 24 24"
|
||||||
@@ -39,6 +40,20 @@
|
|||||||
Execute
|
Execute
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
|
<!-- Plot Button -->
|
||||||
|
<button hx-post="{{ url_for('plot_unsaved_query') }}" hx-target="#sql-plot-results" hx-trigger="click"
|
||||||
|
hx-include="[name='query'],[name='title']"
|
||||||
|
class="flex items-center bg-blue-100 text-white px-4 py-2 rounded hover:bg-blue-300 focus:outline-none focus:ring-2 focus:ring-blue-300">
|
||||||
|
<!-- Plot Icon (Heroicon: Chart Bar) -->
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5"
|
||||||
|
stroke="currentColor" class="h-5 w-5 mr-1">
|
||||||
|
<path stroke-linecap=" round" stroke-linejoin="round"
|
||||||
|
d="M3 13.125C3 12.504 3.504 12 4.125 12h2.25c.621 0 1.125.504 1.125 1.125v6.75C7.5 20.496 6.996 21 6.375 21h-2.25A1.125 1.125 0 0 1 3 19.875v-6.75ZM9.75 8.625c0-.621.504-1.125 1.125-1.125h2.25c.621 0 1.125.504 1.125 1.125v11.25c0 .621-.504 1.125-1.125 1.125h-2.25a1.125 1.125 0 0 1-1.125-1.125V8.625ZM16.5 4.125c0-.621.504-1.125 1.125-1.125h2.25C20.496 3 21 3.504 21 4.125v15.75c0 .621-.504 1.125-1.125 1.125h-2.25a1.125 1.125 0 0 1-1.125-1.125V4.125Z" />
|
||||||
|
</svg>
|
||||||
|
|
||||||
|
Plot
|
||||||
|
</button>
|
||||||
|
|
||||||
<!-- Save Button -->
|
<!-- Save Button -->
|
||||||
<button type="submit" name="action" value="save"
|
<button type="submit" name="action" value="save"
|
||||||
class="flex items-center bg-green-500 text-white px-4 py-2 rounded hover:bg-green-600 focus:outline-none focus:ring-2 focus:ring-green-500">
|
class="flex items-center bg-green-500 text-white px-4 py-2 rounded hover:bg-green-600 focus:outline-none focus:ring-2 focus:ring-green-500">
|
||||||
@@ -54,27 +69,12 @@
|
|||||||
|
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<div class="mt-6">
|
<div id="execute-query-results" class="mt-6">
|
||||||
{% if results %}
|
</div>
|
||||||
<table class="min-w-full bg-white">
|
|
||||||
<thead>
|
<!-- Plot Results Section -->
|
||||||
<tr>
|
<div id="sql-plot-results" class="mt-8">
|
||||||
{% for col in columns %}
|
<!-- Plot will be loaded here via htmx -->
|
||||||
<th class="py-2 px-4 border-b">{{ col }}</th>
|
|
||||||
{% endfor %}
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
{% for row in results %}
|
|
||||||
<tr class="text-center">
|
|
||||||
{% for col in columns %}
|
|
||||||
<td class="py-2 px-4 border-b">{{ row[col] }}</td>
|
|
||||||
{% endfor %}
|
|
||||||
</tr>
|
|
||||||
{% endfor %}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Saved Queries Section -->
|
<!-- Saved Queries Section -->
|
||||||
@@ -120,10 +120,10 @@
|
|||||||
class="flex items-center text-green-500 hover:text-green-700 cursor-pointer"
|
class="flex items-center text-green-500 hover:text-green-700 cursor-pointer"
|
||||||
hx-trigger="click">
|
hx-trigger="click">
|
||||||
<!-- Plot Icon (Heroicon: Chart Bar) -->
|
<!-- Plot Icon (Heroicon: Chart Bar) -->
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-1" fill="none"
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"
|
||||||
viewBox="0 0 24 24" stroke="currentColor">
|
stroke-width="1.5" stroke="currentColor" class="h-5 w-5 mr-1">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
<path stroke-linecap=" round" stroke-linejoin="round"
|
||||||
d="M3 3h2l.4 2M7 13h10l4-8H5.4M7 13L5.4 5M7 13l-2 9m5-9v9m4-9v9m5-9v9" />
|
d="M3 13.125C3 12.504 3.504 12 4.125 12h2.25c.621 0 1.125.504 1.125 1.125v6.75C7.5 20.496 6.996 21 6.375 21h-2.25A1.125 1.125 0 0 1 3 19.875v-6.75ZM9.75 8.625c0-.621.504-1.125 1.125-1.125h2.25c.621 0 1.125.504 1.125 1.125v11.25c0 .621-.504 1.125-1.125 1.125h-2.25a1.125 1.125 0 0 1-1.125-1.125V8.625ZM16.5 4.125c0-.621.504-1.125 1.125-1.125h2.25C20.496 3 21 3.504 21 4.125v15.75c0 .621-.504 1.125-1.125 1.125h-2.25a1.125 1.125 0 0 1-1.125-1.125V4.125Z" />
|
||||||
</svg>
|
</svg>
|
||||||
Plot
|
Plot
|
||||||
</a>
|
</a>
|
||||||
@@ -153,10 +153,4 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Plot Results Section -->
|
|
||||||
<div id="sql-plot-results" class="mt-8">
|
|
||||||
<!-- Plot will be loaded here via htmx -->
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
Reference in New Issue
Block a user