我有一个脚本可以执行数据库操作以及 alembic API 调用以将新创建的数据库升级到 head。我在使用模块级记录器将日志写入文件的 python 记录器实例中遇到问题。
然后脚本调用 alembic.config.main(argv=alembic_args)
来运行迁移。但是,使用原始记录器实例的 alembic 调用后的每个日志语句都不会写入预期的日志文件。
这是一个重现该行为的示例脚本。
#!/usr/bin/env python3
import logging
import os
import alembic.config
from .utilities import get_migration_dir
logging.basicConfig(filename='test.log',
level=logging.DEBUG)
CUR_DIR = os.path.dirname(__file__)
LOG = logging.getLogger('so_log')
LOG.info('Some stuff')
LOG.info('More stuff')
alembic_config = (
'--raiseerr',
'upgrade', 'head'
)
os.chdir(get_migration_dir())
alembic.config.main(argv=alembic_config)
os.chdir(CUR_DIR)
LOG.debug('logging after alembic call.')
LOG.debug('more logging after alembic call.')
print('Code still running after alembic')
日志文件输出
INFO:so_log:Some stuff
INFO:so_log:More stuff
标准输出
INFO [alembic.runtime.migration] Context impl PostgresqlImpl.
INFO [alembic.runtime.migration] Will assume transactional DDL.
print statement before alembic
Code still running after alembic
似乎记录器实例 LOG
在调用 alembic API 后正在丢失上下文或被定向到其他地方。
此外,我已经尝试在产生相同结果的单独线程中运行 alembic 调用。我期望发生的应该是日志语句在使用 alembic 进行迁移后继续写入指定的文件,但这并没有发生。而且,它实际上破坏了之后调用的任何代码的 LOG
实例;除非我在这里遗漏了什么。
最佳答案
这是因为 alembic 使用 alembic.ini
中的 fileConfig
设置日志记录,您可以在您的 env.py
脚本中看到它:
# Interpret the config file for Python logging.
# This line sets up loggers basically.
fileConfig(config.config_file_name)
这有效地覆盖了您的原始记录器配置。
为避免这种情况,您可以简单地从 env.py
中删除这一行,但是这将导致在从控制台运行 alembic
时不会生成任何日志。
一个更强大的选项是通过 alembic.command
而不是 alembic.config.main
运行 alembic 命令。这样你就可以在运行时覆盖 alembic 配置:
from alembic.config import Config
import alembic.command
config = Config('alembic.ini')
config.attributes['configure_logger'] = False
alembic.command.upgrade(config, 'head')
然后在env.py
中:
if config.attributes.get('configure_logger', True):
fileConfig(config.config_file_name)
关于python - 使用 alembic.config.main 重定向日志输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42427487/