Debugging (menampilkan) perintah SQL yang dikirim ke db oleh SQLAlchemy

90

Saya memiliki kelas ORM yang disebut Person, yang mengelilingi tabel person:

Setelah mengatur koneksi ke db dll, saya menjalankan pernyataan:

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

Tabel person tidak berisi data apa pun (hingga saat ini), jadi ketika saya mencetak variabel people, saya mendapatkan daftar kosong.

Saya mengganti nama tabel yang dirujuk di kelas ORM saya People, menjadi people_foo(yang tidak ada).

Saya kemudian menjalankan skrip lagi. Saya terkejut bahwa tidak ada pengecualian yang dilemparkan saat mencoba mengakses tabel yang tidak ada.

Karena itu, saya memiliki 2 pertanyaan berikut:

  1. Bagaimana cara saya mengatur SQLAlchemy sehingga kesalahan db kembali ke skrip?
  2. Bagaimana saya dapat melihat (yaitu mencetak) SQL yang sedang dikirim ke mesin db?

Jika membantu, saya menggunakan PostgreSQL.

[Sunting]

Saya sedang menulis paket. Dalam __main__.pyskrip saya , saya memiliki kode berikut (disingkat di sini):

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

[Sunting2]

Modul umum mengatur logger dengan benar, dan saya dapat menggunakan logger di modul saya yang lain yang mengimpor umum.

Namun dalam dbfuncsmodul, saya mendapatkan kesalahan / peringatan berikut:

Tidak ada penangan yang dapat ditemukan untuk logger "sqlalchemy.engine.base.Engine

morf
sumber
Indensi kode rusak, saya tidak melihat common.setup_logger()panggilan (dengan asumsi itu mengkonfigurasi logging dengan benar) di sini. Selain itu, Anda tidak perlu echo=Truemenggunakan logging.
Denis Otkidach
@denis: Ya, pencatat telah diatur dengan benar di modul umum - Saya dapat masuk ke modul lain. Untuk modul dbfuncs.py. Saya mendapatkan kesalahan: Tidak ada penangan yang dapat ditemukan untuk logger "sqlalchemy.engine.base.Engine
morpheous
1
"Tidak ada penangan yang dapat ditemukan untuk pencatat" berarti pencatat akar tidak memiliki penangan, yaitu pencatat belum dikonfigurasi dengan benar. Mungkin Anda telah mengkonfigurasi beberapa logger tertentu (bukan root) saja (sehingga Anda dapat menggunakannya) atau Anda mengonfigurasinya setelah digunakan pertama kali.
Denis Otkidach

Jawaban:

213

Selain echoparameter create_engine()ada cara yang lebih fleksibel: mengkonfigurasi loggingpernyataan mesin gema:

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

Lihat bagian Konfigurasi Logging pada dokumentasi untuk informasi lebih lanjut.

Denis Otkidach
sumber
1
@ Dennis: inilah yang saya lebih suka lakukan - untuk masuk ke file daripada konsol opf. Saya sudah menggunakan login di .py utama dari paket saya (lihat kode yang saya edit) - setelah melakukan perubahan yang Anda rekomendasikan, sekarang pesan tidak lagi muncul di konsol (bagus), tetapi pesan juga tidak muncul di file log (buruk). Bisakah Anda menjelaskan cara mendapatkan pesan yang masuk ke file?
berubah menjadi
3
Apakah ada cara untuk menambahkan pencetakan cantik? Cara kueri saya dikeluarkan secara default adalah bencana kecil.
rr-
Jadi, apakah ini tidak mungkin untuk masuk ke file pada akhirnya? Saya telah mencari jauh ke dalam dokumen dan tumpukan overflow, tetapi tampaknya tidak ada yang peduli tentang masalah ini, bahkan ketika pertanyaan itu dengan jelas ditanyakan oleh seseorang seperti yang dilakukan morpheous di atas. Apakah ada sesuatu yang jelas di sini?
Romain Vincent
1
@RomainVincent Dimungkinkan untuk mengarahkan informasi yang dicatat ke manapun Anda inginkan, termasuk file, dengan mengkonfigurasi logging.
Denis Otkidach
82

Anda dapat melihat pernyataan SQL yang dikirim ke DB dengan meneruskan echo=Truesaat mesin instance dibuat (biasanya menggunakan create_engine()atauengine_from_config() panggilan dalam kode Anda).

Sebagai contoh:

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

Secara default, pernyataan yang dicatat masuk ke stdout.

Menno Smits
sumber