Debugowanie (wyświetlanie) polecenia SQL wysłanego do bazy danych przez SQLAlchemy

87

Mam klasę ORM o nazwie Osoba, która obejmuje tabelę osób:

Po skonfigurowaniu połączenia z bazą danych itp. Uruchamiam instrukcję:

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

Tabela person nie zawiera żadnych danych (na razie), więc kiedy drukuję zmienną people, otrzymuję pustą listę.

Zmieniłem nazwę tabeli, do której odwołuje się moja klasa ORM People, na people_foo(która nie istnieje).

Następnie ponownie uruchamiam skrypt. Byłem zaskoczony, że nie został zgłoszony żaden wyjątek podczas próby uzyskania dostępu do tabeli, która nie istnieje.

Mam zatem 2 pytania:

  1. Jak mogę skonfigurować SQLAlchemy, aby propagował błędy db z powrotem do skryptu?
  2. Jak mogę wyświetlić (tj. Wydrukować) SQL, który jest wysyłany do silnika db?

Jeśli to pomaga, używam PostgreSQL.

[Edytować]

Piszę pakiet. W swoim __main__.pyskrypcie mam następujący kod (tutaj skrócony):

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

Moduł Common ustawia rejestrator poprawnie i mogę go używać w innych moich modułach, które importują common.

Jednak w dbfuncsmodule otrzymuję następujący błąd / ostrzeżenie:

Nie znaleziono programów obsługi dla programu rejestrującego „sqlalchemy.engine.base.Engine

morfeusz
źródło
Wcięcie kodu jest zepsute, nie widzę tutaj żadnego common.setup_logger()wywołania (zakładając, że skonfigurował poprawnie logowanie). Ponadto nie jest to konieczne echo=Truepodczas korzystania z logowania.
Denis Otkidach
@denis: Tak, rejestrator jest poprawnie skonfigurowany we wspólnym module - jestem w stanie zalogować się do innych modułów. W przypadku modułu dbfuncs.py.
Pojawia
1
„Nie znaleziono programów obsługi dla programu rejestrującego” oznacza, że ​​program rejestrujący root nie ma programów obsługi, tj. Program rejestrujący nie jest jeszcze poprawnie skonfigurowany. Prawdopodobnie skonfigurowałeś tylko jakiś konkretny logger (nie root) (i możesz go używać) lub skonfigurowałeś go po pierwszym użyciu.
Denis Otkidach

Odpowiedzi:

209

Oprócz echoparametru create_engine()istnieje bardziej elastyczny sposób: konfiguracja loggingdo instrukcji silnika echo:

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

Więcej informacji zawiera sekcja Konfigurowanie rejestrowania w dokumentacji.

Denis Otkidach
źródło
1
@dennis: to właśnie wolałbym zrobić - zalogować się do pliku zamiast konsoli opf. Korzystam już z logowania w głównym pliku .py mojego pakietu (zobacz mój edytowany kod) - po wprowadzeniu rekomendowanych przez Ciebie zmian wiadomości nie pojawiają się już na konsoli (dobrze), ale nie pojawiają się też w pliku dziennika (zły). Czy mógłbyś wyjaśnić, jak uzyskać zapisywanie wiadomości w pliku?
morfeous
3
Czy jest jakiś sposób na dodanie ładnego druku? Sposób, w jaki moje zapytania są domyślnie wyprowadzane, to mała katastrofa.
rr-
Czy to niemożliwe, aby ostatecznie zalogować się do pliku? Przeszukałem głęboko dokumentację i przepełnienie stosu, ale wydaje się, że nikt nie przejmuje się tym problemem, nawet jeśli pytanie jest wyraźnie zadane przez kogoś takiego jak Morpheous powyżej. Czy jest tu coś oczywistego?
Romain Vincent
1
@RomainVincent Możliwe jest kierowanie zarejestrowanych informacji w dowolnym miejscu, w tym pliku, poprzez skonfigurowanie rejestrowania.
Denis Otkidach
78

Możesz zobaczyć instrukcje SQL wysyłane do bazy danych, przekazując echo=Truepodczas tworzenia instancji silnika (zwykle przy użyciu funkcji create_engine()lub engine_from_config()w kodzie).

Na przykład:

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

Domyślnie zarejestrowane instrukcje przechodzą na standardowe wyjście.

Menno Smits
źródło