You could use the before_cursor_execute event to log the SQL based on some debugging flag.
http://docs.sqlalchemy.org/en/latest/core/events.html#sqlalchemy.events.ConnectionEvents.before_cursor_execute For example: from sqlalchemy import event DEBUGGING = False @event.listens_for(SomeEngine, 'before_cursor_execute', named=True) def receive_before_cursor_execute(**kw): if DEBUGGING: print kw['statement'] Simon On Wed, Oct 12, 2016 at 8:13 AM, Alfred Perlstein <alfred.perlst...@gmail.com> wrote: > Mike, > > I'm trying to find a nice way to say that this doesn't totally make life > difficult for us. > > Even if we were to use the filter as described, we couldn't use it for an > existing connection, we would HAVE to restart the connection? > > Does that really sound reasonable to you to force users to write all this > scaffolding just to get the SQL emitted for a few lines of code? To me it > really doesn't sound like a framework that facilitates easy debugging. We > basically have to slow down the *entire app* just to get a very small > segment of debug code. > > Is there no way to "toggle" the optimization to reset itself, specifically > this: > >>The SQLAlchemy Engine conserves Python function call overhead by only >> emitting log statements when the current logging level is detected as >> logging.INFO or logging.DEBUG. It only checks this level when a new >> connection is procured from the connection pool. Therefore when changing the >> logging configuration for an already-running application, any Connection >> that’s currently active, or more commonly a Session object that’s active in >> a transaction, won’t log any SQL according to the new configuration until a >> new Connection is procured (in the case of Session, this is after the >> current transaction ends and a new one begins). > > Really? this is really bad and makes what should be a simple debugging > session into a nightmare of scaffolding that has to be written just to do > something that should be super simple, namely: > > "get the sql emitted between these two points of code without having to > write a ton of scaffolding to do so." > > I'm sort of speechless, if possible any advice going forward would help, > even pointers on where to get started in the code. Turning on global debug > and taking a performance hit is not possible. > > Appreciate your help on the matter. > > thanks, > > -Alfred > > > On 10/11/16 11:18 PM, Mike Bayer wrote: >> >> >> >> On 10/11/2016 09:59 PM, Alfred Perlstein wrote: >>> >>> Hello folks, we are using SqlA in a pretty large flask app. >>> >>> One issue we have is that sometimes due to orm, serializers >>> (marshmallow) or other complex code paths we find ourselves doing many >>> more queries than we expected and this causes us a lot of headache. We >>> need to be able to track down the code paths causing the extra SQL. >>> >>> In addition because the codebase is large we can't turn on logging >>> globally otherwise we would drown in noise. >>> >>> The solution we thought would be simple would be to be able to >>> temporarily turn on logging in a single thread of execution or on a >>> single session object... however that seems to be an elusive thing to be >>> able to do. >>> >>> What we have found is that while sqlA offers the ability to *create* an >>> engine with "echo=True", there doesn't seem to be a sane way to *set* >>> echo=True with an existing session. >> >> >> Well first off, SQL logging is a function of the Core, not the ORM, so the >> Session wouldn't know anything about it. >> >>> >>> One could try to set session.engine.echo=True, however it appears that >>> the connection object hung from the engine object grabs the value of >>> "echo" when instantiated and never checks to see if the engine has been >>> reconfigured. >> >> >> this is actually documented in the green note at the end of >> http://docs.sqlalchemy.org/en/rel_1_1/core/engines.html#configuring-logging >> >> >> >> Surely a better way to do this would be to have a method >>> >>> to pass down to the Connection object to enable echo. >> >> >> That's not how Python logging works. Logging in Python is organized as a >> "cross-cutting" concern, meaning a logger presents itself as an open stream >> in which log messages are unconditionally dropped. The configuration of >> what messages to log, when, and where, is accomplished within the logging >> configuration, not within the system that is emitting messages to logging. >> SQLAlchemy's "echo" flag is merely a quick shortcut to a very simplistic log >> output, and additionally it adds a small "block" to remove the overhead of >> emitting messages to the log object if we've detected they aren't being used >> (this occurs independently of the "echo" flag itself). >> >> Any non-trivial use of logging should be using Python's logging system >> directly. The loggers in use are described at >> http://docs.sqlalchemy.org/en/rel_1_1/core/engines.html#configuring-logging. >> >> In this case I'd in the simple case just add "threadid" to the log format >> (https://docs.python.org/2/library/logging.html#logrecord-attributes) and >> use grep against the stream. More ambitiously I'd write a simple >> logging.Filter that only allows messages from a certain thread (some example >> filters such as >> https://docs.python.org/2/howto/logging-cookbook.html#using-filters-to-impart-contextual-information). >> >> >> >>> >>> I've done quite a bit of looking through google and the docs and have >>> simply been unable to find a way do to the following: >>> >>> .... lots of code previous to this line... >>> old_enable = session.log_enable() # turn on logging, return the >>> previous value of logging (so this can be nested) >>> ... do some stuff and see which SQL queries are being made ... >>> session.log_set(old_enable) # restore logging to prior to it being set. >>> ... lots more code without any logging happening. >>> >>> If I were to create a method on engine that would then reconfigure its >>> connection object as well to remedy this, would that be an acceptable >>> patch to the project? Or is there some other trick I am missing? >>> >>> Thank you! >>> -Alfred >>> >>> -- >>> You received this message because you are subscribed to the Google >>> Groups "sqlalchemy" group. >>> To unsubscribe from this group and stop receiving emails from it, send >>> an email to sqlalchemy+unsubscr...@googlegroups.com >>> <mailto:sqlalchemy+unsubscr...@googlegroups.com>. >>> To post to this group, send email to email@example.com >>> <mailto:firstname.lastname@example.org>. >>> Visit this group at https://groups.google.com/group/sqlalchemy. >>> For more options, visit https://groups.google.com/d/optout. >> >> > > -- > You received this message because you are subscribed to the Google Groups > "sqlalchemy" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to sqlalchemy+unsubscr...@googlegroups.com. > To post to this group, send email to email@example.com. > Visit this group at https://groups.google.com/group/sqlalchemy. > For more options, visit https://groups.google.com/d/optout. -- You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To unsubscribe from this group and stop receiving emails from it, send an email to sqlalchemy+unsubscr...@googlegroups.com. To post to this group, send email to firstname.lastname@example.org. Visit this group at https://groups.google.com/group/sqlalchemy. For more options, visit https://groups.google.com/d/optout.