Functional index that is also a UnaryExpression confuses autogeneration

Issue #392 resolved
Dan Craig
created an issue

Ran across an issue that looks related to #282. I added an index that is a coalesce of other columns, but in descending order, like so:

Index('ix_build_times', func.coalesce(Build.finish_time, Build.start_time, Build.queued_time).desc())

Alembic, via Flask-Migrate, found this and created the index when I autogenerated the migration. It probably also printed the reflection warning, but I don't recall.

op.create_index('ix_build_times', 'build', [sa.text(u'coalesce(finish_time, start_time, queued_time) DESC')], unique=False)

But when I had my next, unrelated migration to autogenerate, it again found that index and added it to the migration, which then fails during the upgrade because the index already exists.

Could this be due to the fact that desc() produces a UnaryExpression, even though it's a functional index, causing it to miss the check at ?

I tried adding that index to alembic:excludes in alembic.ini, but it still created it. If there are any other ways to tell Alembic to ignore that, I'd appreciate knowing. For now I guess I'll just have to manually delete the create/drop index lines from autogenerated migrations going forward.


  • postgresql 9.4.1
  • alembic==0.8.8
  • Flask-SQLAlchemy==2.1
  • SQLAlchemy==1.0.15

Comments (4)

  1. Michael Bayer repo owner

    Unwrap unaryexpression when testing for functional index

    Fixed bug in Postgresql "functional index skip" behavior where a functional index that ended in ASC/DESC wouldn't be detected as something we can't compare in autogenerate, leading to duplicate definitions in autogenerated files.

    Change-Id: I0fdfee69a89da575078a687bb4551088fb1b67d7 Fixes: #392

    → <<cset 539227fcbf4a>>

  2. Log in to comment