我正在编写一个小应用程序,使用sqlalchemy将所有内容记录到数据库中。
受到以下内容的启发:
python logging to database
以及
https://docs.pylonsproject.org/projects/pyramid-cookbook/en/latest/logging/sqlalchemy_logger.html
我想出了一个解决方案,对于所有涉及库的日志消息都可以正常工作,除了sqlalchemy(!)本身生成的消息。
这是一个最小化的示例,重现了我的问题:
这是一个最小化的示例,重现了我的问题:
import logging
import datetime
from sqlalchemy import Column, DateTime, String, create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
Base = declarative_base()
# define table
class TblLog(Base):
__tablename__ = 'Tbl_Log'
LOG_TIME = Column(DateTime, primary_key=True)
LOG_NAME = Column(String(100))
LOG_LEVEL = Column(String(100))
LOG_MSG = Column(String(2000))
def __init__(self, time, name, lvl, msg):
self.LOG_TIME = time
self.LOG_NAME = name
self.LOG_LEVEL = lvl
self.LOG_MSG = msg
# custom log handler that emits to the database
class DatabaseHandler(logging.Handler):
def __init__(self, session):
super().__init__()
self.session = session
self.setFormatter(logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s'))
self.setLevel(logging.DEBUG)
def emit(self, record):
self.format(record)
log_time = datetime.datetime.strptime(record.__dict__['asctime'], "%Y-%m-%d %H:%M:%S,%f")
log_record = TblLog(log_time, record.__dict__['name'], record.__dict__['levelname'], record.__dict__['message'])
self.session.add(log_record)
self.session.commit()
启用SQLAlchemy(!)日志记录进行测试:
if __name__ == '__main__':
# simple logging config
logging.basicConfig(
format='%(asctime)s : %(name)s : %(levelname)s : %(message)s',
level=logging.DEBUG,
)
logger_sqlalchemy = logging.getLogger('sqlalchemy')
logger_sqlalchemy.setLevel(logging.INFO)
# test with sqlite in memory database
DB_STRING = 'sqlite:///:memory:'
engine = create_engine(DB_STRING, echo=False)
Base.metadata.create_all(engine)
Session = sessionmaker()
session = Session(bind=engine)
# adding custom handler:
logger_sqlalchemy.addHandler(DatabaseHandler(session))
logger_sqlalchemy.info('this is a test message')
这引发了一个错误:
AttributeError: 'NoneType'对象没有属性'set'
如果需要,我可以粘贴整个回溯。我怀疑问题出现在 TblLog(...) 调用产生日志记录,因此处理程序会向自身发送记录?!
什么是解决此问题的最佳方法,即我是否可以使用 sqlalchemy 处理程序将 sqlalchemy 日志消息写入数据库?
我有些困惑,感谢任何帮助...