I'm switching a legacy project over to autogenerate alembic migrations and it has some indexes that sqlalchemy doesn't recognize. When I run alembic revision --autogenerate migration_name
an empty migration is created (because I have resolved all other inconsistencies) but I get 8 warnings like:
/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
In postgres, I look up the index definition like:
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)
After reading this SO post I tried adding the index after the model definition and to __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)')),
)
Both these changes add warnings (shown below), create an empty migration, and do not remove the original warning. I get that sqlalchemy+alembic can't handle these more complex indexes, but is there any way to silence the warnings?
# 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)
Yes, there are a few ways to silence warnings. If you know where the warnings are being emitted you can create a context manager to capture that emitting function. As shown in the std-lib's documentation
import warnings
def fxn():
warnings.warn("deprecated", DeprecationWarning)
with warnings.catch_warnings():
warnings.simplefilter("ignore")
fxn()
Otherwise the method that is not recommended is to add the following to your main script:
import warnings
warnings.simplefilter("ignore")
A more appropriate way of ignoring warnings (pointed out to me here) is to first check the warning options flag, this allows you to turn warnings back on by running your code with the -W
flag (e.g. python -W
):
import sys
import warnings
if not sys.warnoptions:
warnings.simplefilter("ignore")
And finally to answer your question. The warnings.filterwarnings
method has a module
parameter which can allow you to specify a module you wish to suppress the warnings of. In your case it might be:
import warnings
warnings.filterwarnings("ignore", category=UserWarning, module="alembic.util.messaging")
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With