Debug (visualizzazione) comando SQL inviato al db da SQLAlchemy


87

Ho una classe ORM chiamata Person, che avvolge una tabella person:

Dopo aver impostato la connessione al db ecc., Eseguo l'istruzione:

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

La tabella persona non contiene dati (per ora), quindi quando stampo la variabile peopleottengo un elenco vuoto.

Ho rinominato la tabella a cui si fa riferimento nella mia classe ORM People, in people_foo(che non esiste).

Quindi eseguo di nuovo lo script. Sono rimasto sorpreso dal fatto che non sia stata generata alcuna eccezione durante il tentativo di accedere a una tabella che non esiste.

Ho quindi le seguenti 2 domande:

  1. Come posso impostare SQLAlchemy in modo che propaga gli errori db allo script?
  2. Come posso visualizzare (cioè stampare) l'SQL che viene inviato al motore db?

Se aiuta, sto usando PostgreSQL.

[Modificare]

Sto scrivendo un pacco. Nel mio __main__.pyscript, ho il seguente codice (abbreviato qui):

### __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)

[Modifica2]

Il modulo comune imposta correttamente il logger e posso utilizzare il logger negli altri miei moduli che importano common.

Tuttavia, nel dbfuncsmodulo, ricevo il seguente errore / avviso:

Impossibile trovare gestori per il logger "sqlalchemy.engine.base.Engine


Il rientro del codice è interrotto, non vedo alcuna common.setup_logger()chiamata (supponendo che configuri correttamente la registrazione) qui. Inoltre, non è necessario echo=Truequando si utilizza la registrazione.
Denis Otkidach

@denis: Sì, il logger è impostato correttamente nel modulo comune - sono in grado di accedere ad altri moduli. Per il modulo dbfuncs.py. Ricevo l'errore: non è stato possibile trovare alcun gestore per il logger "sqlalchemy.engine.base.Engine
morpheous

1
"Nessun gestore è stato trovato per il logger" significa che il logger di root non ha gestori, cioè il logger non è ancora configurato correttamente. Probabilmente hai configurato solo un logger specifico (non root) (e quindi puoi usarlo) o lo hai configurato dopo il primo utilizzo.
Denis Otkidach

Risposte:


209

Oltre al echoparametro di create_engine()c'è un modo più flessibile: configurazione loggingper le istruzioni echo engine:

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

Per ulteriori informazioni, vedere la sezione Configurazione della registrazione della documentazione.


1
@dennis: questo è quello che preferirei fare: accedere al file invece di console opf. Sto già utilizzando il login nel .py principale del mio pacchetto (vedi il mio codice modificato) - dopo aver apportato le modifiche consigliate, ora i messaggi non vengono più visualizzati sulla console (buono), ma non compaiono nemmeno nel file di registro (cattivo). Potresti chiarire come ottenere i messaggi registrati su file?
morpheous

3
C'è un modo per aggiungere una bella stampa? Il modo in cui le mie query vengono emesse per impostazione predefinita è un piccolo disastro.
rr-

Quindi è impossibile accedere a un file alla fine? Ho cercato in profondità nella documentazione e nello stack overflow, ma a nessuno sembra importare di questo problema, anche quando la domanda è chiaramente posta da qualcuno come morpheous ha fatto sopra. C'è qualcosa di ovvio qui?
Romain Vincent

1
@RomainVincent È possibile indirizzare le informazioni registrate dove vuoi, incluso il file, configurando la registrazione.
Denis Otkidach

78

È possibile visualizzare le istruzioni SQL inviate al DB passandole echo=Truequando viene creata l'istanza del motore (di solito utilizzando la chiamata create_engine()o engine_from_config()nel codice).

Per esempio:

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

Per impostazione predefinita, le istruzioni registrate vanno a stdout.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.