diff --git a/AUTHORS.md b/AUTHORS.md index 38751a1..3da0059 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -2,6 +2,7 @@ The list of contributors in alphabetical order: +- [Alp Tuna](https://orcid.org/0009-0001-1915-3993) - [Audrius Mecionis](https://orcid.org/0000-0002-3759-1663) - [Camila Diaz](https://orcid.org/0000-0001-5543-797X) - [Daan Rosendal](https://orcid.org/0000-0002-3447-9000) diff --git a/reana_db/alembic/versions/20241119_1051_8da6ccf08af9_add_service_tables.py b/reana_db/alembic/versions/20241119_1051_8da6ccf08af9_add_service_tables.py new file mode 100644 index 0000000..51de624 --- /dev/null +++ b/reana_db/alembic/versions/20241119_1051_8da6ccf08af9_add_service_tables.py @@ -0,0 +1,76 @@ +"""Service tables. + +Revision ID: 8da6ccf08af9 +Revises: 2e82f33ee37d +Create Date: 2024-11-19 10:51:51.199670 + +""" + +import sqlalchemy_utils +import sqlalchemy as sa +from alembic import op + + +# revision identifiers, used by Alembic. +revision = "8da6ccf08af9" +down_revision = "2e82f33ee37d" +branch_labels = None +depends_on = None + + +def upgrade(): + """Upgrade to 8da6ccf08af9 revision.""" + op.create_table( + "service", + sa.Column("id_", sqlalchemy_utils.types.uuid.UUIDType(), nullable=False), + sa.Column("name", sa.String(length=255), nullable=True), + sa.Column("uri", sa.Text(), nullable=True), + sa.Column( + "status", + sa.Enum( + "created", + "running", + "finished", + "failed", + "deleted", + "stopped", + "queued", + "pending", + name="runstatus", + ), + nullable=False, + ), + sa.Column("owner_id", sqlalchemy_utils.types.uuid.UUIDType(), nullable=True), + sa.Column("type_", sa.Enum("dask", name="servicetype"), nullable=False), + sa.ForeignKeyConstraint( + ["owner_id"], ["__reana.user_.id_"], name=op.f("fk_service_owner_id_user_") + ), + sa.PrimaryKeyConstraint("id_", name=op.f("pk_service")), + sa.UniqueConstraint("name", "uri", name=op.f("uq_service_name")), + schema="__reana", + ) + op.create_table( + "workflow_service", + sa.Column("workflow_id", sqlalchemy_utils.types.uuid.UUIDType(), nullable=True), + sa.Column("service_id", sqlalchemy_utils.types.uuid.UUIDType(), nullable=False), + sa.ForeignKeyConstraint( + ["service_id"], + ["__reana.service.id_"], + name=op.f("fk_workflow_service_service_id_service"), + ), + sa.ForeignKeyConstraint( + ["workflow_id"], + ["__reana.workflow.id_"], + name=op.f("fk_workflow_service_workflow_id_workflow"), + ), + sa.PrimaryKeyConstraint("service_id", name=op.f("pk_workflow_service")), + schema="__reana", + ) + # ### end Alembic commands ### + + +def downgrade(): + """Downgrade to 2e82f33ee37d revision.""" + op.drop_table("workflow_service", schema="__reana") + op.drop_table("service", schema="__reana") + # ### end Alembic commands ### diff --git a/reana_db/models.py b/reana_db/models.py index 68edec8..e226bbe 100644 --- a/reana_db/models.py +++ b/reana_db/models.py @@ -460,6 +460,50 @@ def __repr__(self): return "" % self.name +class WorkflowService(Base): + """Workflow Service table.""" + + __tablename__ = "workflow_service" + __table_args__ = {"schema": "__reana"} + + workflow_id = Column(UUIDType, ForeignKey("__reana.workflow.id_"), nullable=True) + service_id = Column(UUIDType, ForeignKey("__reana.service.id_"), primary_key=True) + + def __repr__(self): + """Workflow Service string representation.""" + return f"" + + +class ServiceType(enum.Enum): + """Enumeration of service types.""" + + dask = 0 + + +class Service(Base): + """Service table.""" + + __tablename__ = "service" + id_ = Column(UUIDType, primary_key=True, default=generate_uuid) + name = Column(String(255)) + uri = Column(Text) # uri to access the service + status = Column(Enum(RunStatus), nullable=False, default=RunStatus.created) + owner_id = Column(UUIDType, ForeignKey("__reana.user_.id_")) + type_ = Column( + Enum(ServiceType), + nullable=False, + ) + + __table_args__ = ( + UniqueConstraint("name", "uri"), + {"schema": "__reana"}, + ) + + def __repr__(self): + """Service string representation.""" + return f"" + + class Workflow(Base, Timestamp, QuotaBase): """Workflow table.""" @@ -500,6 +544,13 @@ class Workflow(Base, Timestamp, QuotaBase): backref="workflow", cascade="all, delete", ) + services = relationship( + "Service", + secondary="__reana.workflow_service", + lazy="dynamic", + backref="workflow", + cascade="all, delete", + ) retention_rules = relationship( "WorkspaceRetentionRule", backref="workflow", lazy="dynamic" )