【问题标题】:Using alembic.config.main redirects log output使用 alembic.config.main 重定向日志输出
【发布时间】:2017-07-14 15:03:12
【问题描述】:

我有一个脚本,它执行数据库操作以及 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

在调用 alembic API 后,记录器实例 LOG 似乎正在丢失上下文或被定向到其他地方。

另外,我尝试在一个单独的线程中运行 alembic 调用,结果相同。我期望发生的应该是日志语句在使用 alembic 进行迁移后继续写入指定的文件,但这并没有发生。而且,它实际上破坏了随后调用的任何代码的LOG 实例;除非我只是在这里遗漏了一些东西。

【问题讨论】:

    标签: python logging python-3.5 alembic


    【解决方案1】:

    如果有人遇到这个问题,这对我有用:

    • env.py 中更新fileConfig 调用: fileConfig(config.config_file_name, disable_existing_loggers = False)

    • alembic.ini[logger_root] 的级别更新为较低级别,因为默认设置为WARN

    【讨论】:

      【解决方案2】:

      我刚刚了解到 fileConfig 采用关键字参数 disable_existing_loggers,默认为 True。只需将disable_existing_loggers = False 添加到对env.py 中的fileConfig 的调用中 例如:

      fileConfig(config.config_file_name, disable_existing_loggers=False)
      

      似乎允许两种日志记录配置在不相互干扰的情况下工作(在某些情况下,这可能是首选,而不是必须选择一个)

      【讨论】:

      • 这应该是答案。
      • 禁用现有记录器标志在基于 FASTAPI 的应用程序中为我工作。但是我开始看到每条消息被记录两次。我不得不在我的 FastApi 记录器中使用这个标志:propogate = False。
      【解决方案3】:

      这是因为 alembic 使用来自 alembic.inifileConfig 设置日志记录,您可以在 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)
      

      【讨论】:

      • 啊,我明白了。我最终在运行时在一个单独的进程中运行了 alembic 命令。您的解决方案要好得多。谢谢。
      • 这是一个很好的解决方案。我还想建议我们使用 Config 实例化来设置我们的 configure_logger 值,而不是 config.attributes。 IE。 config = Config('alembic.ini', attributes={'configure_logger': False})
      猜你喜欢
      • 2015-11-25
      • 2013-04-15
      • 2014-08-10
      • 1970-01-01
      • 2016-10-07
      • 2019-08-21
      • 1970-01-01
      • 1970-01-01
      • 2019-03-20
      相关资源
      最近更新 更多