diff --git a/lib/galaxy/model/migrations/alembic/versions_gxy/b182f655505f_add_workflow_source_metadata_column.py b/lib/galaxy/model/migrations/alembic/versions_gxy/b182f655505f_add_workflow_source_metadata_column.py index a389350e3ef..e77da17db38 100644 --- a/lib/galaxy/model/migrations/alembic/versions_gxy/b182f655505f_add_workflow_source_metadata_column.py +++ b/lib/galaxy/model/migrations/alembic/versions_gxy/b182f655505f_add_workflow_source_metadata_column.py @@ -10,8 +10,8 @@ from sqlalchemy import Column from galaxy.model.custom_types import JSONType from galaxy.model.migrations.util import ( + column_exists, drop_column, - ignore_add_column_error, ) # revision identifiers, used by Alembic. @@ -20,12 +20,15 @@ down_revision = "e7b6dcb09efd" branch_labels = None depends_on = None +# database object names user in this revision +table_name = "workflow" +column_name = "source_metadata" + def upgrade(): - table, column = "workflow", "source_metadata" - with ignore_add_column_error(table, column): - op.add_column(table, Column(column, JSONType)) + if not column_exists(table_name, column_name): + op.add_column(table_name, Column(column_name, JSONType)) def downgrade(): - drop_column("workflow", "source_metadata") + drop_column(table_name, column_name) diff --git a/lib/galaxy/model/migrations/util.py b/lib/galaxy/model/migrations/util.py index 39ab37b624b..5163b2ff1c2 100644 --- a/lib/galaxy/model/migrations/util.py +++ b/lib/galaxy/model/migrations/util.py @@ -1,38 +1,18 @@ import logging -from contextlib import contextmanager from alembic import op -from sqlalchemy.exc import ( - OperationalError, - ProgrammingError, -) +from sqlalchemy import inspect log = logging.getLogger(__name__) -def drop_column(table, column): - with op.batch_alter_table(table) as batch_op: - batch_op.drop_column(column) +def drop_column(table_name, column_name): + with op.batch_alter_table(table_name) as batch_op: + batch_op.drop_column(column_name) -@contextmanager -def ignore_add_column_error(table, column): - """ - Use this context manager to wrap statements in upgrade/downgrade functions - in revision files when a statement may cause an error that may be safely - ignored. For example, in revision b182f655505f, if an upgrade operation is - executed on a database that has been previoiusly upgraded via SQLAlchemy - Migrate to version 181, a subsequent upgrade to Alembic may cause such as - error. For more details, see https://github.com/galaxyproject/galaxy/issues/13528. - - We are checking for 2 different error types: OperationalError is raised - for SQLite, ProgrammingError is raised for PostgreSQL. - """ - statement = f"ALTER TABLE {table} ADD COLUMN {column}" - try: - yield - except (ProgrammingError, OperationalError) as e: - if e.statement.startswith(statement): - log.error(f"Ignoring error: {e}") - else: - raise e +def column_exists(table_name, column_name): + bind = op.get_context().bind + insp = inspect(bind) + columns = insp.get_columns(table_name) + return any(c["name"] == column_name for c in columns)