From 841cd3657618694b982f325ffb7f0ce4882071f6 Mon Sep 17 00:00:00 2001 From: Dimitris Theodorou Date: Sun, 11 Jan 2015 15:51:24 +0100 Subject: [PATCH 1/2] add basic app with raw sql alchemy --- test/basic_app_plain_sqlalchemy.py | 35 ++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 test/basic_app_plain_sqlalchemy.py diff --git a/test/basic_app_plain_sqlalchemy.py b/test/basic_app_plain_sqlalchemy.py new file mode 100644 index 0000000..43277db --- /dev/null +++ b/test/basic_app_plain_sqlalchemy.py @@ -0,0 +1,35 @@ +from flask import Flask, render_template +from flask_debugtoolbar import DebugToolbarExtension +from sqlalchemy import Column, Integer, create_engine +from sqlalchemy.orm import Session +from sqlalchemy.ext.declarative import declarative_base + +app = Flask('basic_app_plain_sqlalchemy') +app.debug = True +app.config['SECRET_KEY'] = 'abc123' + +# make sure these are printable in the config panel +app.config['BYTES_VALUE'] = b'\x00' +app.config['UNICODE_VALUE'] = u'\uffff' + + +engine = create_engine('sqlite://') +toolbar = DebugToolbarExtension(app, sqlalchemy_engine=engine) + + +Base = declarative_base() +class Foo(Base): + __tablename__ = 'foo' + id = Column(Integer, primary_key=True) + + +@app.route('/') +def index(): + Base.metadata.create_all(engine) + session = Session(engine) + session.query(Foo).filter_by(id=1).all() + return render_template('basic_app.html') + + +if __name__ == '__main__': + app.run() \ No newline at end of file From d6b782933d2ba63b08a089fa04f7035b7423b87e Mon Sep 17 00:00:00 2001 From: Dimitris Theodorou Date: Sun, 11 Jan 2015 16:11:28 +0100 Subject: [PATCH 2/2] Support raw SQL Alchemy DebugToolbar can receive an sql alchemy engine explicitly, in which case it will install engine events that record queries. Otherwise, it falls back to old Flask-SQLAlchemy behavior. --- flask_debugtoolbar/__init__.py | 18 +++++++++++++++--- flask_debugtoolbar/panels/sqlalchemy.py | 20 +++++++++++++++++++- 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/flask_debugtoolbar/__init__.py b/flask_debugtoolbar/__init__.py index bf8d25f..12032ac 100644 --- a/flask_debugtoolbar/__init__.py +++ b/flask_debugtoolbar/__init__.py @@ -41,8 +41,9 @@ class DebugToolbarExtension(object): _redirect_codes = [301, 302, 303, 304] - def __init__(self, app=None): + def __init__(self, app=None, sqlalchemy_engine=None): self.app = app + self.engine = sqlalchemy_engine self.debug_toolbars = {} # Configure jinja for the internal templates and add url rules @@ -80,8 +81,19 @@ def init_app(self, app): app.add_url_rule('/_debug_toolbar/static/', '_debug_toolbar.static', self.send_static_file) - - app.register_blueprint(module, url_prefix='/_debug_toolbar/views') + if self.engine: + # use 'internal' API from flask_sqlalchemy to install events. + # maybe re-implement this for flask-debugtoolbar + from flask.ext.sqlalchemy import _EngineDebuggingSignalEvents, _record_queries + if _record_queries(app): + _EngineDebuggingSignalEvents( + engine=self.engine, + import_name=app.import_name).register() + + app.register_blueprint( + module, + url_prefix='/_debug_toolbar/views', + sqlalchemy_engine=self.engine) def _default_config(self, app): return { diff --git a/flask_debugtoolbar/panels/sqlalchemy.py b/flask_debugtoolbar/panels/sqlalchemy.py index bf421c8..3931d74 100644 --- a/flask_debugtoolbar/panels/sqlalchemy.py +++ b/flask_debugtoolbar/panels/sqlalchemy.py @@ -12,6 +12,19 @@ from flask_debugtoolbar.utils import format_fname, format_sql import itsdangerous +_engine = None + +@module.record_once +def store_engine(state): + global _engine + _engine = state.options.get('sqlalchemy_engine') + + +def get_engine(): + if _engine is not None: + return _engine + elif sqlalchemy_available: + return SQLAlchemy().get_engine(current_app) _ = lambda x: x @@ -94,6 +107,9 @@ def content(self): msg.append('') return '\n'.join(msg) + if not _engine and not sqlalchemy_available: + return 'No SQLAlchemy engine has been configured.' + queries = get_debug_queries() data = [] for query in queries: @@ -114,7 +130,9 @@ def content(self): defaults=dict(explain=True)) def sql_select(explain=False): statement, params = load_query(request.args['query']) - engine = SQLAlchemy().get_engine(current_app) + engine = get_engine() + if engine is None: + return 'No SQLAlchemy engine has been configured.' if explain: if engine.driver == 'pysqlite':