Налагодження (відображення) команди SQL, надісланої на базу даних SQLAlchemy


89

У мене є клас ORM під назвою Person, який обертається навколо таблиці людини:

Після налаштування підключення до db і т.д., я запускаю оператор:

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

Таблиця person не містить жодних даних (поки що), тому, коли я друкую змінну people, я отримую порожній список.

Я перейменував таблицю, згадану в моєму класі ORM People, на people_foo(яка не існує).

Потім я запускаю сценарій знову. Я був здивований тим, що жодного винятку не було здійснено при спробі отримати доступ до неіснуючої таблиці.

Тому у мене є наступні 2 запитання:

  1. Як я можу налаштувати SQLAlchemy так, щоб він поширював помилки db назад до сценарію?
  2. Як я можу переглянути (тобто надрукувати) SQL, який надсилається на движок db?

Якщо це допомагає, я використовую PostgreSQL.

[Редагувати]

Я пишу пакет. У своєму __main__.pyсценарії я маю такий код (скорочений тут):

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

[Редагувати2]

Загальний модуль правильно налаштовує реєстратор, і я можу використовувати його в інших своїх модулях, що імпортують загальний.

Однак у dbfuncsмодулі я отримую таку помилку / попередження:

Не вдалося знайти обробників для реєстратора "sqlalchemy.engine.base.Engine


Відступ коду порушено, я не бачу тут жодного common.setup_logger()виклику (якщо він правильно налаштовує ведення журналу). Крім того, вам не потрібно echo=Trueпід час використання журналу.
Денис Откідач,

@denis: Так, реєстратор налаштований правильно в загальному модулі - я можу входити в інші модулі. Для модуля dbfuncs.py. Я отримую помилку: Не вдалося знайти обробників для реєстратора "sqlalchemy.engine.base.Engine
morpheous

1
"Не вдається знайти обробники для реєстратора" означає, що кореневий реєстратор не має обробників, тобто реєстратор ще не налаштований належним чином. Можливо, ви налаштували лише якийсь конкретний (не кореневий) реєстратор (і тому ви можете ним користуватися), або налаштували його після першого використання.
Денис Откідач

Відповіді:


210

На додаток до echoпараметра create_engine()існує ще більш гнучкий спосіб: налаштування loggingна ехо-інструкції движка:

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

Для отримання додаткової інформації див. Розділ Налаштування журналювання документації.


1
@dennis: ось що я волів би зробити - замість консолі opf увійти до файлу. Я вже використовую реєстрацію в головному .py мого пакету (див. Мій відредагований код) - після внесення змін, які ви рекомендували, тепер повідомлення більше не відображаються на консолі (добре), але вони також не відображаються у файлі журналу (погано). Не могли б ви пояснити, як отримати повідомлення, які реєструються у файлі?
morpheous

3
Чи є спосіб додати гарний друк? Те, як мої запити виводяться за замовчуванням, є невеликою катастрофою.
rr-

То чи це врешті неможливо увійти у файл? Я глибоко шукав документи і переповнення стеку, але, здається, нікого не хвилює ця проблема, навіть коли це питання явно задає хтось, як це робив вище. Тут є щось очевидне?
Ромен Вінсент

1
@RomainVincent Можна спрямувати зареєстровану інформацію куди завгодно, включаючи файл, налаштувавши журналювання.
Денис Откідач

81

Ви можете бачити, як оператори SQL надсилаються до БД, передаючи їх, echo=Trueколи створюється екземпляр механізму (зазвичай використовуючи create_engine()або engine_from_config()код у вашому коді).

Наприклад:

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

За замовчуванням записані оператори переходять до stdout.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.