【问题标题】:Silencing SQLAlchemy warnings沉默 SQLAlchemy 警告
【发布时间】:2020-04-11 12:14:38
【问题描述】:

我正在切换一个遗留项目以自动生成 alembic 迁移,它有一些 sqlalchemy 无法识别的索引。当我运行alembic revision --autogenerate migration_name 时,会创建一个空迁移(因为我已经解决了所有其他不一致问题),但我收到了 8 个警告,例如:

/project/.venv/lib/python3.6/site-packages/sqlalchemy/dialects/postgresql/base.py:3328: SAWarning: Skipped unsupported reflection of expression-based index idx_name
  "expression-based index %s" % idx_name

在 postgres 中,我查找索引定义如下:

mydb=# SELECT tablename, indexdef FROM pg_indexes WHERE schemaname = 'public' AND indexname = 'idx_name';
 tablename |                                   indexdef                                    
-----------+-------------------------------------------------------------------------------
 plan      | CREATE UNIQUE INDEX idx_name ON public.plan USING btree (lower((name)::text))
(1 row)

阅读this SO post后,我尝试在模型定义后添加索引并添加到​​__table_args__

# add it after model definition
class Plan(db.Model):
    __table_name__ = 'plan'
    # ...

db.Index('this_does_nothing_in_autogenerate', func.lower(Plan.__table__.c.name), unique=True)
# Add it to table_args
class Plan(Base, db.Model):
    __table_name__ = 'plan'
    __table_args__ = (
        db.Index('idx_this_also_does_nothing', text('LOWER(name)')),
    )

这两项更改都添加了警告(如下所示),创建了一个空迁移,并且不删除原始警告。我知道 sqlalchemy+alembic 无法处理这些更复杂的索引,但是有什么方法可以消除警告吗?

# Warning for first method
/home/chriscauley/develop/kennel/.venv/lib/python3.6/site-packages/alembic/util/messaging.py:69: UserWarning: autogenerate skipping functional index this_does_nothing_in_autogenerate; not supported by SQLAlchemy reflection
  warnings.warn(msg)

# warning for second __table_args__ method
/home/chriscauley/develop/kennel/.venv/lib/python3.6/site-packages/alembic/util/messaging.py:69: UserWarning: autogenerate skipping functional index idx_this_also_does_nothing; not supported by SQLAlchemy reflection
  warnings.warn(msg)

【问题讨论】:

    标签: python postgresql sqlalchemy


    【解决方案1】:

    是的,有几种方法可以使警告静音。如果您知道发出警告的位置,您可以创建一个上下文管理器来捕获该发出函数。如std-lib的文档所示

    import warnings
    
    def fxn():
        warnings.warn("deprecated", DeprecationWarning)
    
    with warnings.catch_warnings():
        warnings.simplefilter("ignore")
        fxn()
    

    否则不推荐的方法是将以下内容添加到您的主脚本中:

    import warnings
    
    warnings.simplefilter("ignore")
    

    忽略警告(pointed out to me here)的更合适的方法是首先检查警告选项标志,这允许您通过运行带有-W标志的代码(例如python -W)来重新打开警告:

    import sys
    import warnings
    
    if not sys.warnoptions:
        warnings.simplefilter("ignore")
    

    最后回答你的问题。 warnings.filterwarnings 方法有一个 module 参数,可以让你指定一个你希望抑制警告的模块。在您的情况下,它可能是:

    import warnings
    
    warnings.filterwarnings("ignore", category=UserWarning, module="alembic.util.messaging")
    

    【讨论】:

      猜你喜欢
      • 2020-01-22
      • 2022-12-03
      • 2021-06-29
      • 2016-07-04
      • 1970-01-01
      • 2022-06-14
      • 1970-01-01
      • 2011-07-10
      • 2022-01-25
      相关资源
      最近更新 更多