强制 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
我正在使用 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