Debuggen (Anzeigen) des SQL-Befehls, der von SQLAlchemy an die Datenbank gesendet wird

86

Ich habe eine ORM-Klasse namens Person, die sich um eine Personentabelle wickelt:

Nachdem ich die Verbindung zur Datenbank usw. hergestellt habe, führe ich die folgende Anweisung aus:

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

Die Personentabelle enthält (noch) keine Daten. Wenn ich also die Variable drucke people, erhalte ich eine leere Liste.

Ich benannte die Tabelle nach meiner ORM - Klasse People, zu people_foo(die nicht existiert).

Ich führe dann das Skript erneut aus. Ich war überrascht, dass beim Versuch, auf eine nicht vorhandene Tabelle zuzugreifen, keine Ausnahme ausgelöst wurde.

Ich habe daher folgende 2 Fragen:

  1. Wie kann ich SQLAlchemy so einrichten, dass Datenbankfehler an das Skript zurückgegeben werden?
  2. Wie kann ich die SQL anzeigen (dh drucken), die an die DB-Engine gesendet wird?

Wenn es hilft, verwende ich PostgreSQL.

[Bearbeiten]

Ich schreibe ein Paket. In meinem __main__.pySkript habe ich den folgenden Code (hier abgekürzt):

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

Das Common-Modul richtet den Logger korrekt ein, und ich kann den Logger in meinen anderen Modulen verwenden, die Common importieren.

Im dbfuncsModul wird jedoch der folgende Fehler / die folgende Warnung angezeigt:

Für den Logger "sqlalchemy.engine.base.Engine" wurden keine Handler gefunden

morpheous
quelle
Die Einrückung des Codes ist fehlerhaft. Ich sehe hier keinen common.setup_logger()Aufruf (vorausgesetzt, die Protokollierung wird ordnungsgemäß konfiguriert). Außerdem benötigen Sie keine echo=TrueProtokollierung.
Denis Otkidach
@denis: Ja, der Logger ist im allgemeinen Modul korrekt eingerichtet. Ich kann mich in anderen Modulen anmelden. Für das Modul dbfuncs.py. Ich erhalte die Fehlermeldung: Für den Logger "sqlalchemy.engine.base.Engine
morpheous
1
"Für den Logger konnten keine Handler gefunden werden" bedeutet, dass der Root-Logger keine Handler hat, dh der Logger ist noch nicht richtig konfiguriert. Wahrscheinlich haben Sie nur einen bestimmten (nicht Root-) Logger konfiguriert (und können ihn daher verwenden) oder Sie haben ihn konfiguriert, nachdem er zum ersten Mal verwendet wurde.
Denis Otkidach

Antworten:

202

Zusätzlich zu den echoParametern von create_engine()gibt es eine flexiblere Möglichkeit: Konfigurieren logging, um Engine-Anweisungen wiederzugeben:

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

Siehe Konfigurieren der Protokollierung Abschnitt der Dokumentation für weitere Informationen.

Denis Otkidach
quelle
1
@dennis: das ist, was ich lieber tun würde - um mich in einer Datei statt in der Konsole anzumelden. Ich bin schon in der Verwendung von Logging - Haupt nach den Änderungen ausgeführt hat empfohlen, jetzt wird die Nachrichten nicht mehr erscheinen auf der Konsole (gut), aber sie sind auch nicht in der Protokolldatei erscheinen - Py meines Pakets (siehe meinen editierte Code) (Schlecht). Können Sie klären, wie die Nachrichten in einer Datei protokolliert werden?
morpheous
3
Gibt es eine Möglichkeit, hübschen Druck hinzuzufügen? Die Art und Weise, wie meine Abfragen standardmäßig ausgegeben werden, ist eine kleine Katastrophe.
rr-
Ist es also unmöglich, sich am Ende in eine Datei einzuloggen? Ich habe tief in den Dokumenten und im Stapelüberlauf gesucht, aber niemand scheint sich um dieses Problem zu kümmern, selbst wenn die Frage eindeutig von jemandem gestellt wird, wie es Morpheous oben getan hat. Ist hier etwas offensichtlich?
Romain Vincent
1
@RomainVincent Sie können protokollierte Informationen durch Konfigurieren der Protokollierung an einen beliebigen Ort leiten, einschließlich der Datei.
Denis Otkidach
76

Sie können sehen, dass die SQL-Anweisungen an die Datenbank gesendet werden, indem Sie sie übergeben, echo=Truewenn die Engine-Instanz erstellt wird (normalerweise mithilfe des Aufrufs create_engine()oder engine_from_config()in Ihrem Code).

Beispielsweise:

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

Standardmäßig werden protokollierte Anweisungen an stdout gesendet.

Menno Smits
quelle