Я подозреваю, что проблема возникает из-за того, что вызов TblLog (...) создает запись журнала и, следовательно, обработчик выдает записи самому себе?!
Это не является непосредственной проблемой.Причина сбоя заключается в том, что SQLAlchemy отправляет сообщения журнала во время настройки преобразователя, первое из которых отправляется до того, как преобразователь TblLog
полностью настроен, и, следовательно, ваша ошибка.
Если вы добавите StreamHandler
к своему logger_sqlalchemy
экземпляру до , то DatabaseHandler
вы сможете увидеть сообщения журнала, которые logger_sqlalchemy
получает вплоть до сбоя,Сообщение журнала, которое вызывает это, - (TblLog|Tbl_Log) _post_configure_properties() started
, которое приходит из метода _post_configure_properties()
.Строка документации для этого метода включает в себя:
Это отложенный этап настройки, который должен выполняться после создания всех сопоставителей.
Так что подсказка для конфигурациимаппера для TblLog
не закончено.
Если вы затем удалите DatabaseHandler
из регистратора и просто оставьте StreamHandler
, вы увидите, что этот метод делает (Iтакже удалил ваш basicConfig()
для ясности):
(TblLog|Tbl_Log) _post_configure_properties() started
# this is where your code crashed originally
(TblLog|Tbl_Log) initialize prop LOG_TIME
(TblLog|Tbl_Log) initialize prop LOG_NAME
(TblLog|Tbl_Log) initialize prop LOG_LEVEL
(TblLog|Tbl_Log) initialize prop LOG_MSG
(TblLog|Tbl_Log) _post_configure_properties() complete
Таким образом, как вы можете видеть, некоторая инициализация дескрипторов столбцов, кажется, происходит после того, как было выпущено первое сообщение журнала.Вот почему вы получаете сообщение об ошибке, ORM не готов к тому моменту, когда вы пытаетесь его использовать.
Вы можете создать фиктивный экземпляр TblLog
, чтобы заставить маппер настроить до того, как вы добавитеобработчик, например:
# ensure TblLog mapper configured
TblLog(time=None, name=None, lvl=None, msg=None)
logger_sqlalchemy.addHandler(DatabaseHandler(session))
logger_sqlalchemy.info('this is a test message')
Но тогда вы столкнетесь с новой проблемой: SQLAlchemy генерирует журналы во время процесса сброса / фиксации.Итак, когда первое сообщение журнала сбрасывается в базу данных, оно генерирует новое сообщение журнала, которое само генерирует новое сообщение журнала и т. Д. И т. Д. ..... бесконечная рекурсия.
Итак, мой ответ:
Как лучше всего решить эту проблему, то есть я могу записать сообщения журнала sqlalchemy в базу данных, используя sqlalchemy в обработчике ??
Ответ будет отрицательным, если выпытаясь также захватить sqlalchemy, регистрируя журналирование.
Некоторые возможные решения:
- Не используйте SQLAlchemy для записи сообщений журнала в базу данных.Предполагая, что вы используете SQLAlchemy в других частях вашего приложения, используйте клиент dpapi непосредственно для записи журналов в базу данных и явно не записывайте сообщения журнала клиента в базу данных (в противном случае вы столкнетесь с той же проблемой рекурсии),
- отправьте сообщения журнала в веб-службу, используя
HTTPHandler
, который записывает сообщения журнала в базу данных. - Сохраните журнал sqlalchemy в файл, а все остальное - журналв базу данных.Можно даже настроить задание cron для периодической записи журналов sqlalchemy из файла в базу данных в отдельном процессе.
- Регистрация в качестве службы