70

I am developing an app with flask and SQL Alchemy. I need to display the queries executed to generate a page alongside the time each query took for debugging

What's the best way to do it?

9 Answers 9

138

If you're using the Flask-SQLAlchemy extension and don't want to bother with create_engine, you can set the configuration key SQLALCHEMY_ECHO=True.

http://flask-sqlalchemy.pocoo.org/2.1/config/

Sign up to request clarification or add additional context in comments.

1 Comment

Hi, where can I find this log after enabling it? Edit: It's in the command line / terminal
95
app.config['SQLALCHEMY_ECHO'] = True

Comments

20

I haven't used it myself, but it seems that Flask Debug-toolbar may help with this.

https://github.com/mgood/flask-debugtoolbar

It's a port of the django-debug-toolbar, which can be used for profiling queries. The documentation of Flask Debug-toolbar doesn't mention it, but there is code for a SQLAlchemyDebugPanel.
So I think it may be well worth to take a look at the project, and see if it does what you need.

2 Comments

It works. All you need is to have sqlalchemy set up with the sql alchemy extension and the debug toolbar will pick it up. thanks
If you want to do something else with the queries, calling str() on a query object will give you a string representation of the query that you can do whatever you want with. It likely won't contain the parameterized values, but you'll be able to see the query structure.
10

Late reply but setting "echo=True" in your sqlalchemy create_engine will log the queries executed and the time.

Comments

7

I'm not sure about generating a webpage out of it, but one good way to debug/log DB queries is to use SQLAlchemy's get_debug_queries().

## in app/main/views.py . (my app's main endpoint file)
from flask import current_app
from flask_sqlalchemy import get_debug_queries

@main.after_app_request
def after_request(response):
    for query in get_debug_queries():
        if query.duration >= current_app.config['FLASKY_SLOW_DB_QUERY_TIME']:
            current_app.logger.warning(
                'Slow query: %s\nParameters: %s\nDuration: %fs\nContext: %s\n'
                % (query.statement, query.parameters, query.duration,
                   query.context))
    return response

A lot of things are happening here, let's break it down:

  • The @after_app_request decorator ensures this function is called right before the request closes.
  • The function takes in flask's response object, and iterates through the return of get_debug_queries(), which returns a list.
  • It checks each one of these for its duration, and compares it to a predefined config variable (I set mine to 0.5, in seconds).
  • Lastly, it logs the Query along with its properties to the standard flask logger object (Where this gets logged depends on your app configuration).

Don't forget to set the config variables in your config.py Config class:

SQLALCHEMY_RECORD_QUERIES = True

FLASKY_SLOW_DB_QUERY_TIME = 0.5

1 Comment

I had to change @main.after_app_request to @app.after_request. The app part is just the name of my app, but I had to change after_app_request to after_request.
4

If you are using your own python logging configuration, you might want to simply set the level of the 'sqlalchemy.engine' logger to 'INFO' in your config.

There are many ways of configuring your python logging, but here is an example using logging.config.dictConfig()

import logging.config

logging.config.dictConfig({
   ...
   'loggers': {
       'sqlalchemy.engine': {
           'level': 'INFO',
           'handlers': ...
       }
   }
})

Comments

3

The other answer only works with flask_sqlalchemy, not flask and sqlalchemy.

If you want to use native SQLAlchemy, you can do this as a quick fix: http://yuji.wordpress.com/2014/01/07/use-native-sqlalchemy-in-flask-debugtoolbar/

from flask.ext.sqlalchemy import _EngineDebuggingSignalEvents
_EngineDebuggingSignalEvents(engine, app.import_name).register()
# use at your own risk! a development environment shouldn't really care though!

The explain/select endpoints don't work without wiring them into your project manually, but at the very least your query debugger (count and sql) works. I was trying to understand what kind of queries my alchemy was forming, and I got it.

1 Comment

please note that this still requires installing the Flask-SQLAlchemy extension, because it uses serveral methods from it.
0

In addition to the answer by Cawb07, which solved it for me, be sure you have DEBUG_TB_INTERCEPT_REDIRECTS set to True when you are querying before redirects.

Comments

-1
export FLASK_ENV=development
export FLASK_DEBUG=False

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.