Flask SQLAlchemy display queries for debug

2020-05-24 19:21发布

问题:

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?

回答1:

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:

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/



回答3:

app.config['SQLALCHEMY_ECHO'] = True


回答4:

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



回答5:

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.



回答6:

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



回答7:

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': ...
       }
   }
})


回答8:

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.