diff --git a/lib/tool_shed/webapp/model/__init__.py b/lib/tool_shed/webapp/model/__init__.py index a0b1a178cdd5..445427d65c63 100644 --- a/lib/tool_shed/webapp/model/__init__.py +++ b/lib/tool_shed/webapp/model/__init__.py @@ -97,7 +97,7 @@ class APIKeys(Base): user_id: Mapped[Optional[int]] = mapped_column(ForeignKey("galaxy_user.id"), index=True) key: Mapped[Optional[str]] = mapped_column(TrimmedString(32), index=True, unique=True) user = relationship("User", back_populates="api_keys") - deleted: Mapped[Optional[bool]] = mapped_column(Boolean, index=True, default=False) + deleted: Mapped[Optional[bool]] = mapped_column(index=True, default=False, nullable=False) class User(Base, Dictifiable): diff --git a/lib/tool_shed/webapp/model/migrations/alembic/versions/1b5bf427db25_add_non_nullable_column_deleted_to_api_.py b/lib/tool_shed/webapp/model/migrations/alembic/versions/1b5bf427db25_add_non_nullable_column_deleted_to_api_.py new file mode 100644 index 000000000000..390402f37b53 --- /dev/null +++ b/lib/tool_shed/webapp/model/migrations/alembic/versions/1b5bf427db25_add_non_nullable_column_deleted_to_api_.py @@ -0,0 +1,61 @@ +"""add non-nullable column deleted to API keys + +Revision ID: 1b5bf427db25 +Revises: 969bbf7bcc29 +Create Date: 2024-05-29 21:53:53.516506 + +""" +import sqlalchemy as sa +from alembic import op +from sqlalchemy import ( + Boolean, + Column, + false, + ForeignKey, + func, + Integer, + select, +) + +from galaxy.model.database_object_names import build_index_name +from galaxy.model.migrations.util import ( + add_column, + drop_column, + drop_index, + transaction, +) + +# revision identifiers, used by Alembic. +revision = "1b5bf427db25" +down_revision = "969bbf7bcc29" +branch_labels = None +depends_on = None + +# database object names used in this revision +table_name = "api_keys" +column_name = "deleted" +index_name = build_index_name(table_name, column_name) + + +def upgrade(): + with transaction(): + # Add a deleted column + add_column(table_name, Column(column_name, Boolean(), nullable=False, index=True, server_default=false())) + table = sa.sql.table( + table_name, + Column("id", Integer, primary_key=True), + Column("user_id", ForeignKey("galaxy_user.id"), index=True), + Column(column_name, Boolean, index=True, default=False), + ) + # Set everything to deleted + op.execute(table.update().values(deleted=True)) + # Select the latest api keys + s = select(func.max(table.c.id)).group_by(table.c.user_id) + # Set all of these api keys to not deleted + op.execute(table.update().where(table.c.id.in_(s)).values(deleted=False)) + + +def downgrade(): + with transaction(): + drop_index(index_name, table_name) + drop_column(table_name, column_name)