Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

models: improve indexes #213

Merged
merged 2 commits into from
Nov 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ Changes

Version 0.9.3 (UNRELEASED)
--------------------------

- Changes the ``Workflow`` table to replace the ``run_number`` column with two new columns ``run_number_major`` and ``run_number_minor``, in order to allow for more than 9 restarts.
- Changes the names of database constraints to follow the same naming convention.
- Changes the database indexes to improve performance of common database queries.

Version 0.9.2 (2023-09-26)
--------------------------
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,213 @@
"""Enforce naming convention.

Revision ID: 2461610e9698
Revises: b85c3e601de4
Create Date: 2023-11-28 17:29:58.140440

"""
from alembic import op

# revision identifiers, used by Alembic.
revision = "2461610e9698"
down_revision = "b85c3e601de4"
branch_labels = None
depends_on = None

constraints = [
(
"workflow",
"workflow_pkey",
"pk_workflow",
),
(
"workflow",
"_user_workflow_run_uc",
"uq_workflow_name",
),
(
"workflow",
"workflow_owner_id_fkey",
"fk_workflow_owner_id_user_",
),
(
"user_",
"user__pkey",
"pk_user_",
),
(
"user_",
"user__id__key",
"uq_user__id_",
),
(
"user_",
"user__email_key",
"uq_user__email",
),
(
"user_token",
"user_token_pkey",
"pk_user_token",
),
(
"user_token",
"user_token_token_key",
"uq_user_token_token",
),
(
"user_token",
"user_token_user_id_fkey",
"fk_user_token_user_id_user_",
),
(
"interactive_session",
"interactive_session_pkey",
"pk_interactive_session",
),
(
"interactive_session",
"_interactive_session_uc",
"uq_interactive_session_name",
),
(
"interactive_session",
"interactive_session_owner_id_fkey",
"fk_interactive_session_owner_id_user_",
),
(
"job",
"job_pkey",
"pk_job",
),
(
"job_cache",
"job_cache_pkey",
"pk_job_cache",
),
(
"job_cache",
"job_cache_job_id_fkey",
"fk_job_cache_job_id_job",
),
(
"audit_log",
"audit_log_pkey",
"pk_audit_log",
),
(
"audit_log",
"audit_log_user_id_fkey",
"fk_audit_log_user_id_user_",
),
(
"user_resource",
"user_resource_pkey",
"pk_user_resource",
),
(
"user_resource",
"user_resource_resource_id_fkey",
"fk_user_resource_resource_id_resource",
),
(
"user_resource",
"user_resource_user_id_fkey",
"fk_user_resource_user_id_user_",
),
(
"resource",
"resource_pkey",
"pk_resource",
),
(
"resource",
"resource_name_key",
"uq_resource_name",
),
(
"workflow_session",
"workflow_session_pkey",
"pk_workflow_session",
),
(
"workflow_session",
"workflow_session_session_id_fkey",
"fk_workflow_session_session_id_interactive_session",
),
(
"workflow_session",
"workflow_session_workflow_id_fkey",
"fk_workflow_session_workflow_id_workflow",
),
(
"workspace_retention_rule",
"workspace_retention_rule_pkey",
"pk_workspace_retention_rule",
),
(
"workspace_retention_rule",
"_workspace_retention_rule_uc",
"uq_workspace_retention_rule_workflow_id",
),
(
"workspace_retention_rule",
"workspace_retention_rule_workflow_id_fkey",
"fk_workspace_retention_rule_workflow_id_workflow",
),
(
"workflow_resource",
"workflow_resource_pkey",
"pk_workflow_resource",
),
(
"workflow_resource",
"workflow_resource_resource_id_fkey",
"fk_workflow_resource_resource_id_resource",
),
(
"workflow_resource",
"workflow_resource_workflow_id_fkey",
"fk_workflow_resource_workflow_id_workflow",
),
(
"interactive_session_resource",
"interactive_session_resource_pkey",
"pk_interactive_session_resource",
),
(
"interactive_session_resource",
"interactive_session_resource_resource_id_fkey",
"fk_interactive_session_resource_resource_id_resource",
),
(
"interactive_session_resource",
"interactive_session_resource_session_id_fkey",
"fk_interactive_session_resource_session_id_interactive_session",
),
(
"workspace_retention_audit_log",
"workspace_retention_audit_log_pkey",
"pk_workspace_retention_audit_log",
),
(
"workspace_retention_audit_log",
"workspace_retention_audit_log_workspace_retention_rule_id_fkey",
"fk_workspace_retention_audit_log_workspace_retention_ru_7253",
),
]


def upgrade():
"""Upgrade to 2461610e9698."""
for table, prev_name, new_name in constraints:
op.execute(
f"ALTER TABLE __reana.{table} RENAME CONSTRAINT {prev_name} TO {new_name}"
)


def downgrade():
"""Downgrade to b85c3e601de4."""
for table, prev_name, new_name in constraints:
op.execute(
f"ALTER TABLE __reana.{table} RENAME CONSTRAINT {new_name} TO {prev_name}"
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
"""Improve indexes usage.

Revision ID: eb5309f3d8ee
Revises: 2461610e9698
Create Date: 2023-11-29 13:56:23.588587

"""
from alembic import op


# revision identifiers, used by Alembic.
revision = "eb5309f3d8ee"
down_revision = "2461610e9698"
branch_labels = None
depends_on = None


def upgrade():
"""Upgrade to eb5309f3d8ee."""
# Drop old unique constraint for __reana.workflow and
# create new one with better column order
op.drop_constraint("uq_workflow_name", "workflow", schema="__reana", type_="unique")
op.create_unique_constraint(
"uq_workflow_owner_id",
"workflow",
["owner_id", "name", "run_number_major", "run_number_minor"],
schema="__reana",
)

# Create new index on (workflow_uuid, created) of __reana.job
op.create_index(
"ix___reana_job_workflow_uuid",
"job",
["workflow_uuid", "created"],
unique=False,
schema="__reana",
)

# Create new index on (status) of __reana.workflow
op.create_index(
op.f("ix___reana_workflow_status"),
"workflow",
["status"],
unique=False,
schema="__reana",
)


def downgrade():
"""Downgrade to 2461610e9698."""
# Drop new index on __reana.workflow
op.drop_index(
op.f("ix___reana_workflow_status"), table_name="workflow", schema="__reana"
)

# Delete new index on __reana.job
op.drop_index("ix___reana_job_workflow_uuid", table_name="job", schema="__reana")

# Drop new unique constraint for __reana.workflow and create previous one
op.drop_constraint(
"uq_workflow_owner_id", "workflow", schema="__reana", type_="unique"
)
op.create_unique_constraint(
"uq_workflow_name",
"workflow",
["name", "owner_id", "run_number_major", "run_number_minor"],
schema="__reana",
)
35 changes: 24 additions & 11 deletions reana_db/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,10 @@
Column,
DateTime,
Enum,
Float,
ForeignKey,
Index,
Integer,
MetaData,
String,
Text,
UniqueConstraint,
Expand Down Expand Up @@ -67,7 +68,18 @@
)


Base = declarative_base()
convention = {
"ix": "ix_%(column_0_label)s",
"uq": "uq_%(table_name)s_%(column_0_name)s",
"ck": "ck_%(table_name)s_%(constraint_name)s",
"fk": "fk_%(table_name)s_%(column_0_name)s_%(referred_table_name)s",
"pk": "pk_%(table_name)s",
}
"""Constraint naming convention."""

metadata_obj = MetaData(naming_convention=convention)

Base = declarative_base(metadata=metadata_obj)


def generate_uuid():
Expand Down Expand Up @@ -420,7 +432,7 @@ class InteractiveSession(Base, Timestamp, QuotaBase):
"""Interactive Session table."""

__tablename__ = "interactive_session"
id_ = Column(UUIDType, primary_key=True, unique=True, default=generate_uuid)
id_ = Column(UUIDType, primary_key=True, default=generate_uuid)
name = Column(String(255))
path = Column(Text) # path to access the interactive session
status = Column(Enum(RunStatus), nullable=False, default=RunStatus.created)
Expand All @@ -432,7 +444,7 @@ class InteractiveSession(Base, Timestamp, QuotaBase):
)

__table_args__ = (
UniqueConstraint("name", "path", name="_interactive_session_uc"),
UniqueConstraint("name", "path"),
{"schema": "__reana"},
)

Expand All @@ -448,7 +460,7 @@ class Workflow(Base, Timestamp, QuotaBase):

id_ = Column(UUIDType, primary_key=True)
name = Column(String(255))
status = Column(Enum(RunStatus), default=RunStatus.created)
status = Column(Enum(RunStatus), default=RunStatus.created, index=True)
owner_id = Column(UUIDType, ForeignKey("__reana.user_.id_"))
reana_specification = Column(JSONType)
input_parameters = Column(JSONType)
Expand Down Expand Up @@ -488,11 +500,10 @@ class Workflow(Base, Timestamp, QuotaBase):

__table_args__ = (
UniqueConstraint(
"name",
"owner_id",
"name",
"run_number_major",
"run_number_minor",
name="_user_workflow_run_uc",
),
{"schema": "__reana"},
)
Expand Down Expand Up @@ -810,7 +821,6 @@ class Job(Base, Timestamp):
"""Job table."""

__tablename__ = "job"
__table_args__ = {"schema": "__reana"}

id_ = Column(UUIDType, primary_key=True, default=generate_uuid)
backend_job_id = Column(String(256))
Expand All @@ -829,6 +839,11 @@ class Job(Base, Timestamp):
prettified_cmd = Column(JSONType)
job_name = Column(Text)

__table_args__ = (
Index(None, "workflow_uuid", "created"),
{"schema": "__reana"},
)


@event.listens_for(Job.status, "set")
def job_status_change_listener(job, new_status, old_status, initiator):
Expand Down Expand Up @@ -962,9 +977,7 @@ class WorkspaceRetentionRule(Base):
)

__table_args__ = (
UniqueConstraint(
"workflow_id", "workspace_files", name="_workspace_retention_rule_uc"
),
UniqueConstraint("workflow_id", "workspace_files"),
{"schema": "__reana"},
)

Expand Down