diracx-db 0.0.1a18__py3-none-any.whl → 0.0.1a19__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- diracx/db/__main__.py +1 -0
- diracx/db/sql/__init__.py +9 -1
- diracx/db/sql/job/schema.py +1 -46
- diracx/db/sql/pilot_agents/__init__.py +0 -0
- diracx/db/sql/pilot_agents/db.py +46 -0
- diracx/db/sql/pilot_agents/schema.py +58 -0
- diracx/db/sql/utils/__init__.py +27 -0
- {diracx_db-0.0.1a18.dist-info → diracx_db-0.0.1a19.dist-info}/METADATA +1 -1
- {diracx_db-0.0.1a18.dist-info → diracx_db-0.0.1a19.dist-info}/RECORD +12 -9
- {diracx_db-0.0.1a18.dist-info → diracx_db-0.0.1a19.dist-info}/entry_points.txt +1 -0
- {diracx_db-0.0.1a18.dist-info → diracx_db-0.0.1a19.dist-info}/WHEEL +0 -0
- {diracx_db-0.0.1a18.dist-info → diracx_db-0.0.1a19.dist-info}/top_level.txt +0 -0
    
        diracx/db/__main__.py
    CHANGED
    
    | @@ -31,6 +31,7 @@ async def init_sql(): | |
| 31 31 | 
             
                from diracx.db.sql.utils import BaseSQLDB
         | 
| 32 32 |  | 
| 33 33 | 
             
                for db_name, db_url in BaseSQLDB.available_urls().items():
         | 
| 34 | 
            +
             | 
| 34 35 | 
             
                    logger.info("Initialising %s", db_name)
         | 
| 35 36 | 
             
                    db = BaseSQLDB.available_implementations(db_name)[0](db_url)
         | 
| 36 37 | 
             
                    async with db.engine_context():
         | 
    
        diracx/db/sql/__init__.py
    CHANGED
    
    | @@ -1,9 +1,17 @@ | |
| 1 1 | 
             
            from __future__ import annotations
         | 
| 2 2 |  | 
| 3 | 
            -
            __all__ = ( | 
| 3 | 
            +
            __all__ = (
         | 
| 4 | 
            +
                "AuthDB",
         | 
| 5 | 
            +
                "JobDB",
         | 
| 6 | 
            +
                "JobLoggingDB",
         | 
| 7 | 
            +
                "PilotAgentsDB",
         | 
| 8 | 
            +
                "SandboxMetadataDB",
         | 
| 9 | 
            +
                "TaskQueueDB",
         | 
| 10 | 
            +
            )
         | 
| 4 11 |  | 
| 5 12 | 
             
            from .auth.db import AuthDB
         | 
| 6 13 | 
             
            from .job.db import JobDB
         | 
| 7 14 | 
             
            from .job_logging.db import JobLoggingDB
         | 
| 15 | 
            +
            from .pilot_agents.db import PilotAgentsDB
         | 
| 8 16 | 
             
            from .sandbox_metadata.db import SandboxMetadataDB
         | 
| 9 17 | 
             
            from .task_queue.db import TaskQueueDB
         | 
    
        diracx/db/sql/job/schema.py
    CHANGED
    
    | @@ -1,4 +1,3 @@ | |
| 1 | 
            -
            import sqlalchemy.types as types
         | 
| 2 1 | 
             
            from sqlalchemy import (
         | 
| 3 2 | 
             
                DateTime,
         | 
| 4 3 | 
             
                Enum,
         | 
| @@ -10,37 +9,11 @@ from sqlalchemy import ( | |
| 10 9 | 
             
            )
         | 
| 11 10 | 
             
            from sqlalchemy.orm import declarative_base
         | 
| 12 11 |  | 
| 13 | 
            -
            from ..utils import Column, NullColumn
         | 
| 12 | 
            +
            from ..utils import Column, EnumBackedBool, NullColumn
         | 
| 14 13 |  | 
| 15 14 | 
             
            JobDBBase = declarative_base()
         | 
| 16 15 |  | 
| 17 16 |  | 
| 18 | 
            -
            class EnumBackedBool(types.TypeDecorator):
         | 
| 19 | 
            -
                """Maps a ``EnumBackedBool()`` column to True/False in Python."""
         | 
| 20 | 
            -
             | 
| 21 | 
            -
                impl = types.Enum
         | 
| 22 | 
            -
                cache_ok: bool = True
         | 
| 23 | 
            -
             | 
| 24 | 
            -
                def __init__(self) -> None:
         | 
| 25 | 
            -
                    super().__init__("True", "False")
         | 
| 26 | 
            -
             | 
| 27 | 
            -
                def process_bind_param(self, value, dialect) -> str:
         | 
| 28 | 
            -
                    if value is True:
         | 
| 29 | 
            -
                        return "True"
         | 
| 30 | 
            -
                    elif value is False:
         | 
| 31 | 
            -
                        return "False"
         | 
| 32 | 
            -
                    else:
         | 
| 33 | 
            -
                        raise NotImplementedError(value, dialect)
         | 
| 34 | 
            -
             | 
| 35 | 
            -
                def process_result_value(self, value, dialect) -> bool:
         | 
| 36 | 
            -
                    if value == "True":
         | 
| 37 | 
            -
                        return True
         | 
| 38 | 
            -
                    elif value == "False":
         | 
| 39 | 
            -
                        return False
         | 
| 40 | 
            -
                    else:
         | 
| 41 | 
            -
                        raise NotImplementedError(f"Unknown {value=}")
         | 
| 42 | 
            -
             | 
| 43 | 
            -
             | 
| 44 17 | 
             
            class Jobs(JobDBBase):
         | 
| 45 18 | 
             
                __tablename__ = "Jobs"
         | 
| 46 19 |  | 
| @@ -134,24 +107,6 @@ class AtticJobParameters(JobDBBase): | |
| 134 107 | 
             
                RescheduleCycle = Column(Integer)
         | 
| 135 108 |  | 
| 136 109 |  | 
| 137 | 
            -
            class SiteMask(JobDBBase):
         | 
| 138 | 
            -
                __tablename__ = "SiteMask"
         | 
| 139 | 
            -
                Site = Column(String(64), primary_key=True)
         | 
| 140 | 
            -
                Status = Column(String(64))
         | 
| 141 | 
            -
                LastUpdateTime = Column(DateTime)
         | 
| 142 | 
            -
                Author = Column(String(255))
         | 
| 143 | 
            -
                Comment = Column(Text)
         | 
| 144 | 
            -
             | 
| 145 | 
            -
             | 
| 146 | 
            -
            class SiteMaskLogging(JobDBBase):
         | 
| 147 | 
            -
                __tablename__ = "SiteMaskLogging"
         | 
| 148 | 
            -
                Site = Column(String(64), primary_key=True)
         | 
| 149 | 
            -
                UpdateTime = Column(DateTime, primary_key=True)
         | 
| 150 | 
            -
                Status = Column(String(64))
         | 
| 151 | 
            -
                Author = Column(String(255))
         | 
| 152 | 
            -
                Comment = Column(Text)
         | 
| 153 | 
            -
             | 
| 154 | 
            -
             | 
| 155 110 | 
             
            class HeartBeatLoggingInfo(JobDBBase):
         | 
| 156 111 | 
             
                __tablename__ = "HeartBeatLoggingInfo"
         | 
| 157 112 | 
             
                JobID = Column(
         | 
| 
            File without changes
         | 
| @@ -0,0 +1,46 @@ | |
| 1 | 
            +
            from __future__ import annotations
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            from datetime import datetime, timezone
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            from sqlalchemy import insert
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            from ..utils import BaseSQLDB
         | 
| 8 | 
            +
            from .schema import PilotAgents, PilotAgentsDBBase
         | 
| 9 | 
            +
             | 
| 10 | 
            +
             | 
| 11 | 
            +
            class PilotAgentsDB(BaseSQLDB):
         | 
| 12 | 
            +
                """PilotAgentsDB class is a front-end to the PilotAgents Database."""
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                metadata = PilotAgentsDBBase.metadata
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                async def add_pilot_references(
         | 
| 17 | 
            +
                    self,
         | 
| 18 | 
            +
                    pilot_ref: list[str],
         | 
| 19 | 
            +
                    vo: str,
         | 
| 20 | 
            +
                    grid_type: str = "DIRAC",
         | 
| 21 | 
            +
                    pilot_stamps: dict | None = None,
         | 
| 22 | 
            +
                ) -> None:
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                    if pilot_stamps is None:
         | 
| 25 | 
            +
                        pilot_stamps = {}
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                    now = datetime.now(tz=timezone.utc)
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                    # Prepare the list of dictionaries for bulk insertion
         | 
| 30 | 
            +
                    values = [
         | 
| 31 | 
            +
                        {
         | 
| 32 | 
            +
                            "PilotJobReference": ref,
         | 
| 33 | 
            +
                            "VO": vo,
         | 
| 34 | 
            +
                            "GridType": grid_type,
         | 
| 35 | 
            +
                            "SubmissionTime": now,
         | 
| 36 | 
            +
                            "LastUpdateTime": now,
         | 
| 37 | 
            +
                            "Status": "Submitted",
         | 
| 38 | 
            +
                            "PilotStamp": pilot_stamps.get(ref, ""),
         | 
| 39 | 
            +
                        }
         | 
| 40 | 
            +
                        for ref in pilot_ref
         | 
| 41 | 
            +
                    ]
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                    # Insert multiple rows in a single execute call
         | 
| 44 | 
            +
                    stmt = insert(PilotAgents).values(values)
         | 
| 45 | 
            +
                    await self.conn.execute(stmt)
         | 
| 46 | 
            +
                    return
         | 
| @@ -0,0 +1,58 @@ | |
| 1 | 
            +
            from sqlalchemy import (
         | 
| 2 | 
            +
                DateTime,
         | 
| 3 | 
            +
                Double,
         | 
| 4 | 
            +
                Index,
         | 
| 5 | 
            +
                Integer,
         | 
| 6 | 
            +
                String,
         | 
| 7 | 
            +
                Text,
         | 
| 8 | 
            +
            )
         | 
| 9 | 
            +
            from sqlalchemy.orm import declarative_base
         | 
| 10 | 
            +
             | 
| 11 | 
            +
            from ..utils import Column, EnumBackedBool, NullColumn
         | 
| 12 | 
            +
             | 
| 13 | 
            +
            PilotAgentsDBBase = declarative_base()
         | 
| 14 | 
            +
             | 
| 15 | 
            +
             | 
| 16 | 
            +
            class PilotAgents(PilotAgentsDBBase):
         | 
| 17 | 
            +
                __tablename__ = "PilotAgents"
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                PilotID = Column("PilotID", Integer, autoincrement=True, primary_key=True)
         | 
| 20 | 
            +
                InitialJobID = Column("InitialJobID", Integer, default=0)
         | 
| 21 | 
            +
                CurrentJobID = Column("CurrentJobID", Integer, default=0)
         | 
| 22 | 
            +
                PilotJobReference = Column("PilotJobReference", String(255), default="Unknown")
         | 
| 23 | 
            +
                PilotStamp = Column("PilotStamp", String(32), default="")
         | 
| 24 | 
            +
                DestinationSite = Column("DestinationSite", String(128), default="NotAssigned")
         | 
| 25 | 
            +
                Queue = Column("Queue", String(128), default="Unknown")
         | 
| 26 | 
            +
                GridSite = Column("GridSite", String(128), default="Unknown")
         | 
| 27 | 
            +
                VO = Column("VO", String(128))
         | 
| 28 | 
            +
                GridType = Column("GridType", String(32), default="LCG")
         | 
| 29 | 
            +
                BenchMark = Column("BenchMark", Double, default=0.0)
         | 
| 30 | 
            +
                SubmissionTime = NullColumn("SubmissionTime", DateTime)
         | 
| 31 | 
            +
                LastUpdateTime = NullColumn("LastUpdateTime", DateTime)
         | 
| 32 | 
            +
                Status = Column("Status", String(32), default="Unknown")
         | 
| 33 | 
            +
                StatusReason = Column("StatusReason", String(255), default="Unknown")
         | 
| 34 | 
            +
                AccountingSent = Column("AccountingSent", EnumBackedBool(), default=False)
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                __table_args__ = (
         | 
| 37 | 
            +
                    Index("PilotJobReference", "PilotJobReference"),
         | 
| 38 | 
            +
                    Index("Status", "Status"),
         | 
| 39 | 
            +
                    Index("Statuskey", "GridSite", "DestinationSite", "Status"),
         | 
| 40 | 
            +
                )
         | 
| 41 | 
            +
             | 
| 42 | 
            +
             | 
| 43 | 
            +
            class JobToPilotMapping(PilotAgentsDBBase):
         | 
| 44 | 
            +
                __tablename__ = "JobToPilotMapping"
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                PilotID = Column("PilotID", Integer, primary_key=True)
         | 
| 47 | 
            +
                JobID = Column("JobID", Integer, primary_key=True)
         | 
| 48 | 
            +
                StartTime = Column("StartTime", DateTime)
         | 
| 49 | 
            +
             | 
| 50 | 
            +
                __table_args__ = (Index("JobID", "JobID"), Index("PilotID", "PilotID"))
         | 
| 51 | 
            +
             | 
| 52 | 
            +
             | 
| 53 | 
            +
            class PilotOutput(PilotAgentsDBBase):
         | 
| 54 | 
            +
                __tablename__ = "PilotOutput"
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                PilotID = Column("PilotID", Integer, primary_key=True)
         | 
| 57 | 
            +
                StdOutput = Column("StdOutput", Text)
         | 
| 58 | 
            +
                StdError = Column("StdError", Text)
         | 
    
        diracx/db/sql/utils/__init__.py
    CHANGED
    
    | @@ -13,6 +13,7 @@ from datetime import datetime, timedelta, timezone | |
| 13 13 | 
             
            from functools import partial
         | 
| 14 14 | 
             
            from typing import TYPE_CHECKING, Self, cast
         | 
| 15 15 |  | 
| 16 | 
            +
            import sqlalchemy.types as types
         | 
| 16 17 | 
             
            from pydantic import TypeAdapter
         | 
| 17 18 | 
             
            from sqlalchemy import Column as RawColumn
         | 
| 18 19 | 
             
            from sqlalchemy import DateTime, Enum, MetaData, select
         | 
| @@ -128,6 +129,32 @@ def EnumColumn(enum_type, **kwargs): | |
| 128 129 | 
             
                return Column(Enum(enum_type, native_enum=False, length=16), **kwargs)
         | 
| 129 130 |  | 
| 130 131 |  | 
| 132 | 
            +
            class EnumBackedBool(types.TypeDecorator):
         | 
| 133 | 
            +
                """Maps a ``EnumBackedBool()`` column to True/False in Python."""
         | 
| 134 | 
            +
             | 
| 135 | 
            +
                impl = types.Enum
         | 
| 136 | 
            +
                cache_ok: bool = True
         | 
| 137 | 
            +
             | 
| 138 | 
            +
                def __init__(self) -> None:
         | 
| 139 | 
            +
                    super().__init__("True", "False")
         | 
| 140 | 
            +
             | 
| 141 | 
            +
                def process_bind_param(self, value, dialect) -> str:
         | 
| 142 | 
            +
                    if value is True:
         | 
| 143 | 
            +
                        return "True"
         | 
| 144 | 
            +
                    elif value is False:
         | 
| 145 | 
            +
                        return "False"
         | 
| 146 | 
            +
                    else:
         | 
| 147 | 
            +
                        raise NotImplementedError(value, dialect)
         | 
| 148 | 
            +
             | 
| 149 | 
            +
                def process_result_value(self, value, dialect) -> bool:
         | 
| 150 | 
            +
                    if value == "True":
         | 
| 151 | 
            +
                        return True
         | 
| 152 | 
            +
                    elif value == "False":
         | 
| 153 | 
            +
                        return False
         | 
| 154 | 
            +
                    else:
         | 
| 155 | 
            +
                        raise NotImplementedError(f"Unknown {value=}")
         | 
| 156 | 
            +
             | 
| 157 | 
            +
             | 
| 131 158 | 
             
            class SQLDBError(Exception):
         | 
| 132 159 | 
             
                pass
         | 
| 133 160 |  | 
| @@ -1,11 +1,11 @@ | |
| 1 1 | 
             
            diracx/db/__init__.py,sha256=2oeUeVwZq53bo_ZOflEYZsBn7tcR5Tzb2AIu0TAWELM,109
         | 
| 2 | 
            -
            diracx/db/__main__.py,sha256= | 
| 2 | 
            +
            diracx/db/__main__.py,sha256=tU4tp3OAClYCiPMxlRj524sZGBx9oy4CoWHd8pMuEEs,1715
         | 
| 3 3 | 
             
            diracx/db/exceptions.py,sha256=-LSkEwsvjwU7vXqx-xeLvLKInTRAhjwB7K_AKfQcIH8,41
         | 
| 4 4 | 
             
            diracx/db/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
         | 
| 5 5 | 
             
            diracx/db/os/__init__.py,sha256=IZr6z6SefrRvuC8sTC4RmB3_wwOyEt1GzpDuwSMH8O4,112
         | 
| 6 6 | 
             
            diracx/db/os/job_parameters.py,sha256=Knca19uT2G-5FI7MOFlaOAXeHn4ecPVLIH30TiwhaTw,858
         | 
| 7 7 | 
             
            diracx/db/os/utils.py,sha256=9UyhgMqaI8loh8chW2zHW-9JAOtH5YfktC-d-uY5Wnk,11346
         | 
| 8 | 
            -
            diracx/db/sql/__init__.py,sha256= | 
| 8 | 
            +
            diracx/db/sql/__init__.py,sha256=JYu0b0IVhoXy3lX2m2r2dmAjsRS7IbECBUMEDvX0Te4,391
         | 
| 9 9 | 
             
            diracx/db/sql/auth/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
         | 
| 10 10 | 
             
            diracx/db/sql/auth/db.py,sha256=Wi4oeHCL4pPiaysZEx8R0KNk9BDxncAAtOD2qnD-NnY,10206
         | 
| 11 11 | 
             
            diracx/db/sql/auth/schema.py,sha256=W5whp1ZK_SNt-wxWVRBegmrc9IgqCR1LFY1FWwUlEBs,2828
         | 
| @@ -14,20 +14,23 @@ diracx/db/sql/dummy/db.py,sha256=4Xyo7gUh_5b6Q2a_ggJG6e7fCtc9HrP_BRXfKGfqZIs,164 | |
| 14 14 | 
             
            diracx/db/sql/dummy/schema.py,sha256=uEkGDNVZbmJecytkHY1CO-M1MiKxe5w1_h0joJMPC9E,680
         | 
| 15 15 | 
             
            diracx/db/sql/job/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
         | 
| 16 16 | 
             
            diracx/db/sql/job/db.py,sha256=DaU1SGeXl7TqX1QxT1RldCeMIOYGnzNwkqBrwgGE90A,16248
         | 
| 17 | 
            -
            diracx/db/sql/job/schema.py,sha256= | 
| 17 | 
            +
            diracx/db/sql/job/schema.py,sha256=w9Ht9LyVK-fB5T9-hYGsqifzneeG2YP123j1-Mx8Xio,4283
         | 
| 18 18 | 
             
            diracx/db/sql/job_logging/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
         | 
| 19 19 | 
             
            diracx/db/sql/job_logging/db.py,sha256=OGVHYIDcWhGYVfHacsz9DEPSoJ7aRbKVoQOyCCj8XvU,5036
         | 
| 20 20 | 
             
            diracx/db/sql/job_logging/schema.py,sha256=dD2arl-6bffeK8INT6tZ1HWEpJuYTx2iNiVzswVXXF8,812
         | 
| 21 | 
            +
            diracx/db/sql/pilot_agents/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
         | 
| 22 | 
            +
            diracx/db/sql/pilot_agents/db.py,sha256=7-cuCbh_KhM0jlybsHMWV-W66bHsPHIVBpbuqwjncj0,1232
         | 
| 23 | 
            +
            diracx/db/sql/pilot_agents/schema.py,sha256=d4sVlhWpMVgHguS-VlDR3zqM0Yj5QVEjon3gBgrr-kk,2091
         | 
| 21 24 | 
             
            diracx/db/sql/sandbox_metadata/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
         | 
| 22 25 | 
             
            diracx/db/sql/sandbox_metadata/db.py,sha256=ZoiKjs-Rdd4p-kOZOLoUkpP0xGIp0oGjou3D2oP_6GE,6452
         | 
| 23 26 | 
             
            diracx/db/sql/sandbox_metadata/schema.py,sha256=rngYYkJxBhjETBHGLD1CTipDGe44mRYR0wdaFoAJwp0,1400
         | 
| 24 27 | 
             
            diracx/db/sql/task_queue/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
         | 
| 25 28 | 
             
            diracx/db/sql/task_queue/db.py,sha256=e6yauZO0nWaUVqjqQycH8iPO4wXLXaC82eaIq1K_KI8,9102
         | 
| 26 29 | 
             
            diracx/db/sql/task_queue/schema.py,sha256=fvzQyCw_xWAOWTLW6Qrp1m-WzEKb0tlYmafoLTbCy1I,3222
         | 
| 27 | 
            -
            diracx/db/sql/utils/__init__.py,sha256= | 
| 30 | 
            +
            diracx/db/sql/utils/__init__.py,sha256=8YcDra_P_FL3QIDzl53HvN1tHUE396F0tGKB-TPQxeM,15541
         | 
| 28 31 | 
             
            diracx/db/sql/utils/job_status.py,sha256=GNQTKiyguhnB348mLIB7BT-PEOEKpKljR4JzvOd_h8M,10414
         | 
| 29 | 
            -
            diracx_db-0.0. | 
| 30 | 
            -
            diracx_db-0.0. | 
| 31 | 
            -
            diracx_db-0.0. | 
| 32 | 
            -
            diracx_db-0.0. | 
| 33 | 
            -
            diracx_db-0.0. | 
| 32 | 
            +
            diracx_db-0.0.1a19.dist-info/METADATA,sha256=_e0zgiSjl92T83BUpBXkEHzMeCcLcr4L_sE9h9v_iwQ,688
         | 
| 33 | 
            +
            diracx_db-0.0.1a19.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
         | 
| 34 | 
            +
            diracx_db-0.0.1a19.dist-info/entry_points.txt,sha256=YLI4f6640bri8Ud6Jt9WNq79pSTVQAkfUasb9f75fR8,315
         | 
| 35 | 
            +
            diracx_db-0.0.1a19.dist-info/top_level.txt,sha256=vJx10tdRlBX3rF2Psgk5jlwVGZNcL3m_7iQWwgPXt-U,7
         | 
| 36 | 
            +
            diracx_db-0.0.1a19.dist-info/RECORD,,
         | 
| @@ -5,5 +5,6 @@ JobParametersDB = diracx.db.os:JobParametersDB | |
| 5 5 | 
             
            AuthDB = diracx.db.sql:AuthDB
         | 
| 6 6 | 
             
            JobDB = diracx.db.sql:JobDB
         | 
| 7 7 | 
             
            JobLoggingDB = diracx.db.sql:JobLoggingDB
         | 
| 8 | 
            +
            PilotAgentsDB = diracx.db.sql:PilotAgentsDB
         | 
| 8 9 | 
             
            SandboxMetadataDB = diracx.db.sql:SandboxMetadataDB
         | 
| 9 10 | 
             
            TaskQueueDB = diracx.db.sql:TaskQueueDB
         | 
| 
            File without changes
         | 
| 
            File without changes
         |