强制 SQLAlchemy 仅记录到文件

Force SQLAlchemy to Log to File Only

我正在使用 Python (3.8) 和 SQLAlchemy (1.4.29) 来处理 Web 应用程序项目的 SQL 数据库。根据 SQLAlchemy 的 Engine Configuration docs, I can use Python's logging 模块来控制日志输出的位置和方式。

我希望 SQLAlchemy 引擎输出到文件 (logs/actions.log),并阻止记录器输出到 sys.stdout,所以我采用了这种方法:

import logging
import sqlalchemy as sq
from sqlalchemy import orm

logger = logging.getLogger('sqlalchemy')
handler = logging.FileHandler("logs/actions.log")

logger.handlers = []

handler.setLevel(logging.DEBUG)
logger.addHandler(handler)

engine = sq.create_engine(DB_URI, echo=True)
session = (orm.sessionmaker(engine))()

但这将在文件和 sys.stdout 中输出。我怎样才能防止这种情况发生?谢谢!

是的,我看过类似的问题,他们没有帮助解决我的问题。

尝试添加 logger.propagate = False - 记录到 sqlalchemy 记录器的事件可能也会传递到附加到根记录器的 StreamHandler。您可以打印 logging.getLogger().handlers 以查看是否是这种情况。如果不是,请检查最后两行是否添加了一个您不知道的处理程序,方法是在这两个调用之后打印 logger.handlers

您需要调用 logger 的 setLevel 方法,这样 logger 的级别将允许您希望处理程序处理的级别的消息。默认情况下,SQLAlchemy 记录器具有警告级别,因此如果您希望处理程序处理调试消息,那么记录器也必须如此。

此示例演示如何配置“sqlalchemy.engine”记录器。

import logging

import sqlalchemy as sa

logfile = 'actions.log'

logging.basicConfig()
logger = logging.getLogger('sqlalchemy')
logger.propagate = False
# Ensure logfile is truncated for demonstration
handler = logging.FileHandler(logfile, mode='w')
logger.setLevel(logging.DEBUG)

logger.handlers = []

handler.setLevel(logging.DEBUG)
logger.addHandler(handler)

# Suppress output from child loggers
logging.getLogger('sqlalchemy.engine').handlers = []
logging.getLogger('sqlalchemy.pool').handlers = []

engine = sa.create_engine('sqlite://', echo=False, echo_pool=False)
with engine.connect() as conn:
    conn.execute(sa.text('select 1 = 2'))

with open(logfile) as f:
    print(f.read())

输出

Created new connection <sqlite3.Connection object at 0x7fbadd93ef40>
Connection <sqlite3.Connection object at 0x7fbadd93ef40> checked out from pool
select 1 = 2
[generated in 0.00022s] ()
Col ('1 = 2',)
Connection <sqlite3.Connection object at 0x7fbadd93ef40> being returned to pool
Connection <sqlite3.Connection object at 0x7fbadd93ef40> rollback-on-return