mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-09-24 16:30:27 +08:00
Merge pull request #13624 from ic4f/dev_alembic_fix3
Check if column exists before executing upgrade/downgrade operations in select revisions
This commit is contained in:
+8
-5
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user