diff --git a/flaskext/debugtoolbar/__init__.py b/flaskext/debugtoolbar/__init__.py index 419e788..7e243d0 100644 --- a/flaskext/debugtoolbar/__init__.py +++ b/flaskext/debugtoolbar/__init__.py @@ -8,7 +8,10 @@ from werkzeug.exceptions import HTTPException from werkzeug.urls import url_quote_plus from flaskext.debugtoolbar.toolbar import DebugToolbar -from flaskext.debugtoolbar.views import module +from flask import Module + + +module = Module(__name__) def replace_insensitive(string, target, replacement): """Similar to string.replace() but is case insensitive @@ -55,7 +58,6 @@ class DebugToolbarExtension(object): loader=PackageLoader(__name__, 'templates')) self.jinja_env.filters['urlencode'] = url_quote_plus - app.register_module(module, url_prefix='/_debug_toolbar/views') app.add_url_rule('/_debug_toolbar/static/', '_debug_toolbar.static', self.send_static_file) @@ -70,6 +72,10 @@ class DebugToolbarExtension(object): """ req = _request_ctx_stack.top.request app = current_app + + if 'debugtoolbar' not in app.modules: + app.register_module(module, url_prefix='/_debug_toolbar/views') + try: if req.routing_exception is not None: raise req.routing_exception diff --git a/flaskext/debugtoolbar/panels/sqlalchemy.py b/flaskext/debugtoolbar/panels/sqlalchemy.py index a06b5b8..bef6620 100644 --- a/flaskext/debugtoolbar/panels/sqlalchemy.py +++ b/flaskext/debugtoolbar/panels/sqlalchemy.py @@ -1,14 +1,20 @@ import hashlib +import simplejson + try: from flaskext.sqlalchemy import get_debug_queries except ImportError: get_debug_queries = None -from flask import current_app, json +from flask import request, current_app, abort, json from flaskext.debugtoolbar.panels import DebugPanel from flaskext.debugtoolbar.utils import format_fname, format_sql +from flaskext.sqlalchemy import SQLAlchemy + +from flaskext.debugtoolbar import module + _ = lambda x: x @@ -71,4 +77,62 @@ class SQLAlchemyDebugPanel(DebugPanel): }) return self.render('panels/sqlalchemy.html', { 'queries': data}) +# Panel views +@module.route('/sqlalchemy/sql_select', methods=['GET', 'POST']) +def sql_select(render): + statement = request.args['sql'] + params = request.args['params'] + + # Validate hash + hash = hashlib.sha1( + current_app.config['SECRET_KEY'] + statement + params).hexdigest() + if hash != request.args['hash']: + return abort(406) + + # Make sure it is a select statement + if not statement.lower().strip().startswith('select'): + return abort(406) + + params = simplejson.loads(params) + + db = SQLAlchemy(current_app) + + result = db.engine.execute(statement, params) + return render('panels/sqlalchemy_select.html', { + 'result': result.fetchall(), + 'headers': result.keys(), + 'sql': format_sql(statement, params), + 'duration': float(request.args['duration']), + }) + +@module.route('/sqlalchemy/sql_explain', methods=['GET', 'POST']) +def sql_explain(render): + statement = request.args['sql'] + params = request.args['params'] + + # Validate hash + hash = hashlib.sha1( + current_app.config['SECRET_KEY'] + statement + params).hexdigest() + if hash != request.args['hash']: + return abort(406) + + # Make sure it is a select statement + if not statement.lower().strip().startswith('select'): + return abort(406) + + params = json.loads(params) + + db = SQLAlchemy(current_app) + if db.engine.driver == 'pysqlite': + query = 'EXPLAIN QUERY PLAN %s' % statement + else: + query = 'EXPLAIN %s' % statement + + result = db.engine.execute(query, params) + return render('panels/sqlalchemy_explain.html', { + 'result': result.fetchall(), + 'headers': result.keys(), + 'sql': format_sql(statement, params), + 'duration': float(request.args['duration']), + }) \ No newline at end of file diff --git a/flaskext/debugtoolbar/templates/panels/sqlalchemy.html b/flaskext/debugtoolbar/templates/panels/sqlalchemy.html index c98fb7c..633bbe8 100644 --- a/flaskext/debugtoolbar/templates/panels/sqlalchemy.html +++ b/flaskext/debugtoolbar/templates/panels/sqlalchemy.html @@ -14,8 +14,8 @@ {% if query.params %} {% if query.is_select %} - SELECT
- EXPLAIN
+ SELECT
+ EXPLAIN
{% if is_mysql %} PROFILE
{% endif %} diff --git a/flaskext/debugtoolbar/views.py b/flaskext/debugtoolbar/views.py deleted file mode 100644 index 220de7a..0000000 --- a/flaskext/debugtoolbar/views.py +++ /dev/null @@ -1,68 +0,0 @@ -import hashlib - -from flask import Module, request, current_app, abort, json -from flaskext.sqlalchemy import SQLAlchemy -from flaskext.debugtoolbar.utils import format_sql - - -module = Module(__name__) - - - -@module.route('/sql_select', methods=['GET', 'POST']) -def sql_select(render): - statement = request.args['sql'] - params = request.args['params'] - - # Validate hash - hash = hashlib.sha1( - current_app.config['SECRET_KEY'] + statement + params).hexdigest() - if hash != request.args['hash']: - return abort(406) - - # Make sure it is a select statement - if not statement.lower().strip().startswith('select'): - return abort(406) - - params = simplejson.loads(params) - - db = SQLAlchemy(current_app) - - result = db.engine.execute(statement, params) - return render('panels/sqlalchemy_select.html', { - 'result': result.fetchall(), - 'headers': result.keys(), - 'sql': format_sql(statement, params), - 'duration': float(request.args['duration']), - }) - -@module.route('/sql_explain', methods=['GET', 'POST']) -def sql_explain(render): - statement = request.args['sql'] - params = request.args['params'] - - # Validate hash - hash = hashlib.sha1( - current_app.config['SECRET_KEY'] + statement + params).hexdigest() - if hash != request.args['hash']: - return abort(406) - - # Make sure it is a select statement - if not statement.lower().strip().startswith('select'): - return abort(406) - - params = json.loads(params) - - db = SQLAlchemy(current_app) - if db.engine.driver == 'pysqlite': - query = 'EXPLAIN QUERY PLAN %s' % statement - else: - query = 'EXPLAIN %s' % statement - - result = db.engine.execute(query, params) - return render('panels/sqlalchemy_explain.html', { - 'result': result.fetchall(), - 'headers': result.keys(), - 'sql': format_sql(statement, params), - 'duration': float(request.args['duration']), - })