alembic migration upgrade throws UnboundExecutionError:

Bug #1326654 reported by Venkat Sundaram
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
Barbican
Fix Released
Medium
Venkat Sundaram

Bug Description

I tried to upgrade my barbican db (mysql) from the initial version "1a0c2cdafb38" to "13d127569afa" using the script bin/barbican-db-manage.py

This is per instructions in the "Manually" section of the wiki: https://github.com/cloudkeep/barbican/wiki/Database-Migrations

$ bin/barbican-db-manage.py -d mysql://<username>:<password>@localhost/<barbican db> upgrade -v 13d127569afa

2014-06-05 05:26:58.753 921 CRITICAL barbican-db-manage [-] UnboundExecutionError: MetaData object is not bound to an Engine or Connection. Execution can not proceed without a database to execute against.

upon investigation, traced the issue to the following lines in the file: barbican/model/migration/alembic_migrations/versions/13d127569afa_create_secret_store_metadata_table.py

def upgrade():
    meta = sa.MetaData()
>> meta.reflect(bind=rep._ENGINE, only=['secret_store_metadata'])
    if 'secret_store_metadata' not in meta.tables.keys():
   ---snipped----

rep._ENGINE was None and hence the error. If I comment these three lines, the alembic create table operation succeeds.

Questions:
1. Am I doing something wrong in running the migration script ?
2. In another setup (non-development box), I don't even see the barbican-db-manage.py script installed. Shouldn't this be included in the setup.cfg file ? Or, is it a work-in-progress ?
3. The data migration wiki says that the check for the table's existence is required to guard against the same migration code called at the start of the api server. Isn't the alembic versioning approach intended to solve this exact problem ? I mean, just plugin the "upgrade"/"downgrade" methods and leave the versioning to alembic ? Even if this check is inevitable, not sure why sqlalchemy has to be used (which caused the issue for me above) in this migration script. I was able to get it to migrate without errors using the following (alembic only)code:

def upgrade():
    ctx = op.get_context()
    con = op.get_bind()
    table_exists = ctx.dialect.has_table(con.engine, 'secret_store_metadata')
    if not table_exists:
   ---snipped----

Is there any reason not to use the existing alembic context (which is already inside a transaction) like this ?

Thanks

Revision history for this message
John Wood (john-wood-w) wrote :

Hello Venkat, just responding to your questions above...

I'm assuming you are referring to this wiki: https://github.com/cloudkeep/barbican/wiki/Database-Migrations

1) You are running the script as expected, but if the automatic mode is enabled (so when Barbican boots it auto upgrades the database) then it shouldn't be required.

2) If it is not in the setup.cfg file, then that's an oversight, good catch!

3) As for checking for table existence, I think the issue stems from SQLAlchemy synching vs Alembic version processing. There are conditions in which the two modes seem to fight each other. At any rate, it seems your code suggestion is actually the better approach than what was added to the migration wiki.

Would you be up for modifying the current failing migration module with your suggested code changes (per this bug), and then updating that section of the wiki to favor using your approach? Would you also be up for adding a CR to add the migration script to the setup.cfg file?

Changed in barbican:
milestone: none → juno-1
Revision history for this message
Venkat Sundaram (tsv) wrote :

Sure John. Would be happy to contribute :)
Thanks for the quick response.

Changed in barbican:
assignee: nobody → Venkat Sundaram (tsv)
Revision history for this message
Venkat Sundaram (tsv) wrote :

Opened Bug #1326862 for adding the script to setup.cfg

Revision history for this message
John Wood (john-wood-w) wrote :

Thanks Venkat!

Revision history for this message
OpenStack Infra (hudson-openstack) wrote : Fix proposed to barbican (master)

Fix proposed to branch: master
Review: https://review.openstack.org/98321

Changed in barbican:
status: New → In Progress
Revision history for this message
OpenStack Infra (hudson-openstack) wrote : Fix merged to barbican (master)

Reviewed: https://review.openstack.org/98321
Committed: https://git.openstack.org/cgit/openstack/barbican/commit/?id=08c63fdbcb22978290fc4f67c648708cc2d7ebd6
Submitter: Jenkins
Branch: master

commit 08c63fdbcb22978290fc4f67c648708cc2d7ebd6
Author: tsv <email address hidden>
Date: Fri Jun 6 01:43:00 2014 -0600

    Fix data migration script error

    There are two types of data migration:
    1. Automatic - happens during barbican api startup
    2. Manual - run on demand when migration is required

    The Manual step is done by running the bin/barbican-db-manage.py
    script. This script fails with an "UnboundExecutionError" due
    to a conflict between SQLAlchemy synching vs Alembic version
    processing in checking for the existence of the table. This commit
    fixes the issue by replacing the SQLAlchemy metadata calls with
    alembic calls by reusing the context/connection from the existing
    "op".

    Change-Id: I9bf65594a9e76b3f98d67bbd47a9cc7b97298de0
    Closes-Bug: #1326654

Changed in barbican:
status: In Progress → Fix Committed
Revision history for this message
Venkat Sundaram (tsv) wrote :
Revision history for this message
John Wood (john-wood-w) wrote :

Thanks for the updates Venkat!

John Wood (john-wood-w)
Changed in barbican:
status: Fix Committed → Fix Released
Thierry Carrez (ttx)
Changed in barbican:
milestone: juno-1 → 2014.2
Changed in barbican:
importance: Undecided → Medium
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.