146

I have an ORM class called Person, which wraps around a person table:

After setting up the connection to the db etc, I run the statement:

people = session.query(Person).all()

The person table does not contain any data (as yet), so when I print the variable people, I get an empty list.

I renamed the table referred to in my ORM class People, to people_foo (which does not exist).

I then run the script again. I was surprised that no exception was thrown when attempting to access a table that does not exist.

I therefore have the following 2 questions:

  1. How may I setup SQLAlchemy so that it propagates db errors back to the script?
  2. How may I view (i.e. print) the SQL that is being sent to the db engine?

If it helps, I am using PostgreSQL.

[Edit]

I am writing a package. In my __main__.py script, I have the following code (shortened here):

### __main__.py
import common # imports logging and defines logging setup funcs etc

logger = logging.getLogger(__name__)


def main():    
    parser = OptionParser(usage="%prog [options] <commands>",
                          version="%prog 1.0")

    commands = OptionGroup(parser, "commands")

    parser.add_option(
        "-l",
        "--logfile",
        dest="logfile",
        metavar="FILE",
        help="log to FILE. if not set, no logging will be done"
    )

    parser.add_option(
        "--level",
        dest="loglevel",
        metavar="LOG LEVEL",
        help="Debug level. if not set, level will default to low"
    )

    # Set defaults if not specified
    if not options.loglevel:
        loglevel = 1
    else:
        loglevel = options.loglevel

    if not options.logfile:
        logfilename = 'datafeed.log'
    else:
        logfilename = options.logfile

    common.setup_logger(False, logfilename, loglevel) 

       # and so on ...



        #### dbfuncs.py


import logging

    # not sure how to 'bind' to the logger in __main__.py
    logging.getLogger('sqlalchemy.engine').setLevel(logging.INFO)

    engine = create_engine('postgres://postgres:pwd@localhost:port/dbname', echo=True)

[Edit2]

Common module sets the logger up correctly, and I can use the logger in my other modules that import common.

However in dbfuncs module, I am getting the following error/warning:

No handlers could be found for logger "sqlalchemy.engine.base.Engine

SuperShoot
  • 9,880
  • 2
  • 38
  • 55
morpheous
  • 16,270
  • 32
  • 89
  • 120
  • Indention of code is broken, I see no `common.setup_logger()` call (assuming it configure logging properly) here. Also, you don't need `echo=True` when using logging. – Denis Otkidach Jun 01 '10 at 15:35
  • @denis: Yes the logger is setup correctly in the common module - I am able to log in other modules. For the dbfuncs.py module. I get the error: No handlers could be found for logger "sqlalchemy.engine.base.Engine – morpheous Jun 01 '10 at 17:17
  • 1
    "No handlers could be found for logger" means root logger has no handlers, i.e. logger _is not_ configured properly yet. Probably you have configured some specific (not root) logger only (and so you can use it) or you configured it _after_ it's used first time. – Denis Otkidach Jun 02 '10 at 08:36

2 Answers2

292

In addition to echo parameter of create_engine() there is a more flexible way: configuring logging to echo engine statements:

import logging
logging.basicConfig()
logging.getLogger('sqlalchemy.engine').setLevel(logging.INFO)

See Configuring Logging section of documentation for more information.

tossbyte
  • 380
  • 4
  • 9
Denis Otkidach
  • 32,032
  • 8
  • 79
  • 100
  • 1
    @dennis: this is what I would rather do - to log to file instead opf console. I am already using logging in the __main__.py of my package (see my edited code) - after making the changes you recommended, now the messages are no longer appearing on console (good), but they are also not appearing in the log file (bad). Could you clarify how to get the messages logged to file? – morpheous Jun 01 '10 at 14:57
  • 3
    Is there any way to add pretty printing? The way my queries are outputted by default is a small disaster. – rr- Apr 20 '16 at 19:02
  • 2
    So is this impossible to log into a file in the end? I have searched deep into the docs and stack overflow, but nobody seems to care about this problem, even when the question is clearly asked by someone like morpheous did above. Is there something obvious here? – Romain Vincent Nov 10 '17 at 10:35
  • 3
    @RomainVincent It's possible to direct logged information wherever you want, including file, by configuring logging. – Denis Otkidach Nov 10 '17 at 14:29
  • Just put those bunch of code in your dbcon or anywhere – Tanjin Alam Jan 24 '23 at 16:55
135

You can see the SQL statements being sent to the DB by passing echo=True when the engine instance is created (usually using the create_engine() or engine_from_config() call in your code).

For example:

engine = sqlalchemy.create_engine('postgres://foo/bar', echo=True)

By default, logged statements go to stdout.

SuperShoot
  • 9,880
  • 2
  • 38
  • 55
Menno Smits
  • 2,074
  • 1
  • 13
  • 12