From 96fbf70164c3495c1064b431dadf3dcc384a888d Mon Sep 17 00:00:00 2001 From: Jorge Lisa <64639359+AcquaDiGiorgio@users.noreply.github.com> Date: Mon, 16 Sep 2024 11:34:09 +0200 Subject: [PATCH 1/7] feat: Add PostgreSQL integration to diracx-db --- diracx-core/src/diracx/core/settings.py | 2 +- diracx-db/pyproject.toml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/diracx-core/src/diracx/core/settings.py b/diracx-core/src/diracx/core/settings.py index f451b72c..ad056f36 100644 --- a/diracx-core/src/diracx/core/settings.py +++ b/diracx-core/src/diracx/core/settings.py @@ -18,7 +18,7 @@ T = TypeVar("T") SqlalchemyDsn = Annotated[ - AnyUrl, UrlConstraints(allowed_schemes={"sqlite+aiosqlite", "mysql+aiomysql"}) + AnyUrl, UrlConstraints(allowed_schemes={"sqlite+aiosqlite", "mysql+aiomysql", "postgresql+asyncpg"}) ] diff --git a/diracx-db/pyproject.toml b/diracx-db/pyproject.toml index f7a145fc..8f3a4e92 100644 --- a/diracx-db/pyproject.toml +++ b/diracx-db/pyproject.toml @@ -19,6 +19,7 @@ dependencies = [ "opensearch-py[async]", "pydantic >=2.4", "sqlalchemy[aiomysql,aiosqlite] >= 2", + "asyncpg", ] dynamic = ["version"] From ef817ae8af71e720b11a085fb828bde9aa4884f8 Mon Sep 17 00:00:00 2001 From: Jorge Lisa <64639359+AcquaDiGiorgio@users.noreply.github.com> Date: Mon, 16 Sep 2024 17:33:22 +0200 Subject: [PATCH 2/7] feat: remove mysql specific code --- diracx-db/src/diracx/db/sql/dummy/db.py | 4 ++-- diracx-db/src/diracx/db/sql/job/db.py | 2 +- diracx-db/src/diracx/db/sql/job/schema.py | 4 ++-- diracx-db/src/diracx/db/sql/sandbox_metadata/db.py | 2 +- diracx-db/src/diracx/db/sql/utils/__init__.py | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/diracx-db/src/diracx/db/sql/dummy/db.py b/diracx-db/src/diracx/db/sql/dummy/db.py index 8a1c7942..68e35554 100644 --- a/diracx-db/src/diracx/db/sql/dummy/db.py +++ b/diracx-db/src/diracx/db/sql/dummy/db.py @@ -40,7 +40,7 @@ async def insert_owner(self, name: str) -> int: stmt = insert(Owners).values(name=name) result = await self.conn.execute(stmt) # await self.engine.commit() - return result.lastrowid + return result.inserted_primary_key[0] async def insert_car(self, license_plate: UUID, model: str, owner_id: int) -> int: stmt = insert(Cars).values( @@ -49,4 +49,4 @@ async def insert_car(self, license_plate: UUID, model: str, owner_id: int) -> in result = await self.conn.execute(stmt) # await self.engine.commit() - return result.lastrowid + return result.inserted_primary_key[0] diff --git a/diracx-db/src/diracx/db/sql/job/db.py b/diracx-db/src/diracx/db/sql/job/db.py index af0efa70..dd4e8098 100644 --- a/diracx-db/src/diracx/db/sql/job/db.py +++ b/diracx-db/src/diracx/db/sql/job/db.py @@ -135,7 +135,7 @@ async def _insertNewJDL(self, jdl) -> int: ) result = await self.conn.execute(stmt) # await self.engine.commit() - return result.lastrowid + return result.inserted_primary_key[0] async def _insertJob(self, jobData: dict[str, Any]): stmt = insert(Jobs).values(jobData) diff --git a/diracx-db/src/diracx/db/sql/job/schema.py b/diracx-db/src/diracx/db/sql/job/schema.py index 7f77cb15..768531c7 100644 --- a/diracx-db/src/diracx/db/sql/job/schema.py +++ b/diracx-db/src/diracx/db/sql/job/schema.py @@ -22,7 +22,7 @@ class EnumBackedBool(types.TypeDecorator): cache_ok: bool = True def __init__(self) -> None: - super().__init__("True", "False") + super().__init__("True", "False", name="EnumBackedBool") def process_bind_param(self, value, dialect) -> str: if value is True: @@ -72,7 +72,7 @@ class Jobs(JobDBBase): VerifiedFlag = Column("VerifiedFlag", EnumBackedBool(), default=False) # TODO: Should this be True/False/"Failed"? Or True/False/Null? AccountedFlag = Column( - "AccountedFlag", Enum("True", "False", "Failed"), default="False" + "AccountedFlag", Enum("True", "False", "Failed", name="AccountedFlag"), default="False" ) __table_args__ = ( diff --git a/diracx-db/src/diracx/db/sql/sandbox_metadata/db.py b/diracx-db/src/diracx/db/sql/sandbox_metadata/db.py index db72a7f9..6e3ef6a2 100644 --- a/diracx-db/src/diracx/db/sql/sandbox_metadata/db.py +++ b/diracx-db/src/diracx/db/sql/sandbox_metadata/db.py @@ -32,7 +32,7 @@ async def upsert_owner(self, user: UserInfo) -> int: VO=user.vo, ) result = await self.conn.execute(stmt) - return result.lastrowid + return result.inserted_primary_key[0] @staticmethod def get_pfn(bucket_name: str, user: UserInfo, sandbox_info: SandboxInfo) -> str: diff --git a/diracx-db/src/diracx/db/sql/utils/__init__.py b/diracx-db/src/diracx/db/sql/utils/__init__.py index 41b142d5..388fdd80 100644 --- a/diracx-db/src/diracx/db/sql/utils/__init__.py +++ b/diracx-db/src/diracx/db/sql/utils/__init__.py @@ -65,7 +65,7 @@ def substract_date(**kwargs: float) -> datetime: def EnumColumn(enum_type, **kwargs): - return Column(Enum(enum_type, native_enum=False, length=16), **kwargs) + return Column(Enum(enum_type, native_enum=False, length=16, name=str(enum_type)), **kwargs) class SQLDBError(Exception): From a148ac22265e4865b6b292ce1ac34c601da5d001 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 16 Sep 2024 15:57:25 +0000 Subject: [PATCH 3/7] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- diracx-core/src/diracx/core/settings.py | 5 ++++- diracx-db/src/diracx/db/sql/job/schema.py | 4 +++- diracx-db/src/diracx/db/sql/utils/__init__.py | 4 +++- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/diracx-core/src/diracx/core/settings.py b/diracx-core/src/diracx/core/settings.py index a6f94416..407fea18 100644 --- a/diracx-core/src/diracx/core/settings.py +++ b/diracx-core/src/diracx/core/settings.py @@ -19,7 +19,10 @@ T = TypeVar("T") SqlalchemyDsn = Annotated[ - AnyUrl, UrlConstraints(allowed_schemes={"sqlite+aiosqlite", "mysql+aiomysql", "postgresql+asyncpg"}) + AnyUrl, + UrlConstraints( + allowed_schemes={"sqlite+aiosqlite", "mysql+aiomysql", "postgresql+asyncpg"} + ), ] diff --git a/diracx-db/src/diracx/db/sql/job/schema.py b/diracx-db/src/diracx/db/sql/job/schema.py index 768531c7..5b2c68d1 100644 --- a/diracx-db/src/diracx/db/sql/job/schema.py +++ b/diracx-db/src/diracx/db/sql/job/schema.py @@ -72,7 +72,9 @@ class Jobs(JobDBBase): VerifiedFlag = Column("VerifiedFlag", EnumBackedBool(), default=False) # TODO: Should this be True/False/"Failed"? Or True/False/Null? AccountedFlag = Column( - "AccountedFlag", Enum("True", "False", "Failed", name="AccountedFlag"), default="False" + "AccountedFlag", + Enum("True", "False", "Failed", name="AccountedFlag"), + default="False", ) __table_args__ = ( diff --git a/diracx-db/src/diracx/db/sql/utils/__init__.py b/diracx-db/src/diracx/db/sql/utils/__init__.py index 4edab09b..e5b49bb2 100644 --- a/diracx-db/src/diracx/db/sql/utils/__init__.py +++ b/diracx-db/src/diracx/db/sql/utils/__init__.py @@ -125,7 +125,9 @@ def substract_date(**kwargs: float) -> datetime: def EnumColumn(enum_type, **kwargs): - return Column(Enum(enum_type, native_enum=False, length=16, name=str(enum_type)), **kwargs) + return Column( + Enum(enum_type, native_enum=False, length=16, name=str(enum_type)), **kwargs + ) class SQLDBError(Exception): From 606f290a4b262edb5077c610161d8cc9fd52bcfb Mon Sep 17 00:00:00 2001 From: Jorge Lisa <64639359+AcquaDiGiorgio@users.noreply.github.com> Date: Tue, 17 Sep 2024 13:49:30 +0200 Subject: [PATCH 4/7] feat: Modify integration tests to execute against both MySQL and PostgreSQL using matrix note: Setted up chart github url to point to my fork, MUST change later --- .github/workflows/main.yml | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 9ca7be88..464645fb 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -77,6 +77,14 @@ jobs: pytest-integration: runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + include: + - dbName: "MySQL" + cliOption: "" + - dbName: "PostgreSQL" + cliOption: "--postgres" steps: - name: Checkout code uses: actions/checkout@v4 @@ -90,10 +98,10 @@ jobs: pip install pytest-github-actions-annotate-failures pip install git+https://github.com/DIRACGrid/DIRAC.git@integration pip install ./diracx-core/[testing] ./diracx-api/[testing] ./diracx-cli/[testing] ./diracx-client/[testing] ./diracx-routers/[testing] ./diracx-db/[testing] ./diracx-testing/ - - name: Start demo + - name: Start demo using ${{ matrix.dbName }} run: | - git clone https://github.com/DIRACGrid/diracx-charts.git ../diracx-charts - ../diracx-charts/run_demo.sh --enable-open-telemetry --enable-coverage --exit-when-done --set-value developer.autoReload=false --ci-values ../diracx-charts/demo/ci_values.yaml $PWD + git clone -b diracx-issue-147-postgres-integration https://github.com/AcquaDiGiorgio/diracx-charts.git ../diracx-charts + ../diracx-charts/run_demo.sh ${{ matrix.cliOption }} --enable-open-telemetry --enable-coverage --exit-when-done --set-value developer.autoReload=false --ci-values ../diracx-charts/demo/ci_values.yaml $PWD - name: Debugging information run: | DIRACX_DEMO_DIR=$PWD/../diracx-charts/.demo From a9bcf7a9c93935cd888e9b45669601d2959e6117 Mon Sep 17 00:00:00 2001 From: Jorge Lisa <64639359+AcquaDiGiorgio@users.noreply.github.com> Date: Fri, 20 Sep 2024 11:23:19 +0200 Subject: [PATCH 5/7] feat: add postgres to the debbuging information of the integration tests fix: pre-commit --- .github/workflows/main.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 464645fb..27e01774 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -98,7 +98,7 @@ jobs: pip install pytest-github-actions-annotate-failures pip install git+https://github.com/DIRACGrid/DIRAC.git@integration pip install ./diracx-core/[testing] ./diracx-api/[testing] ./diracx-cli/[testing] ./diracx-client/[testing] ./diracx-routers/[testing] ./diracx-db/[testing] ./diracx-testing/ - - name: Start demo using ${{ matrix.dbName }} + - name: Start demo using ${{ matrix.dbName }} run: | git clone -b diracx-issue-147-postgres-integration https://github.com/AcquaDiGiorgio/diracx-charts.git ../diracx-charts ../diracx-charts/run_demo.sh ${{ matrix.cliOption }} --enable-open-telemetry --enable-coverage --exit-when-done --set-value developer.autoReload=false --ci-values ../diracx-charts/demo/ci_values.yaml $PWD @@ -108,7 +108,7 @@ jobs: export KUBECONFIG=${DIRACX_DEMO_DIR}/kube.conf export PATH=${DIRACX_DEMO_DIR}:$PATH kubectl get pods - for pod_name in $(kubectl get pods -o json | jq -r '.items[] | .metadata.name' | grep -vE '(dex|minio|mysql|rabbitmq|opensearch)'); do + for pod_name in $(kubectl get pods -o json | jq -r '.items[] | .metadata.name' | grep -vE '(dex|minio|mysql|postgres|rabbitmq|opensearch)'); do echo "${pod_name}" kubectl describe pod/"${pod_name}" || true for container_name in $(kubectl get pods $pod_name -o jsonpath='{.spec.initContainers[*].name} {.spec.containers[*].name}'); do From 46ce608d6ea6f16053b230947c656a26fea1a05c Mon Sep 17 00:00:00 2001 From: Jorge Lisa <64639359+AcquaDiGiorgio@users.noreply.github.com> Date: Tue, 24 Sep 2024 16:15:01 +0200 Subject: [PATCH 6/7] fix: Change JobDB schema to make datetime columns properly accept a timezone Mysql removes the timezone before inserting, but Postgresql throws an error --- diracx-db/src/diracx/db/sql/job/schema.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/diracx-db/src/diracx/db/sql/job/schema.py b/diracx-db/src/diracx/db/sql/job/schema.py index 5b2c68d1..b7baf359 100644 --- a/diracx-db/src/diracx/db/sql/job/schema.py +++ b/diracx-db/src/diracx/db/sql/job/schema.py @@ -58,12 +58,12 @@ class Jobs(JobDBBase): Owner = Column("Owner", String(64), default="Unknown") OwnerGroup = Column("OwnerGroup", String(128), default="Unknown") VO = Column("VO", String(32)) - SubmissionTime = NullColumn("SubmissionTime", DateTime) - RescheduleTime = NullColumn("RescheduleTime", DateTime) - LastUpdateTime = NullColumn("LastUpdateTime", DateTime) - StartExecTime = NullColumn("StartExecTime", DateTime) - HeartBeatTime = NullColumn("HeartBeatTime", DateTime) - EndExecTime = NullColumn("EndExecTime", DateTime) + SubmissionTime = NullColumn("SubmissionTime", DateTime(timezone=True)) + RescheduleTime = NullColumn("RescheduleTime", DateTime(timezone=True)) + LastUpdateTime = NullColumn("LastUpdateTime", DateTime(timezone=True)) + StartExecTime = NullColumn("StartExecTime", DateTime(timezone=True)) + HeartBeatTime = NullColumn("HeartBeatTime", DateTime(timezone=True)) + EndExecTime = NullColumn("EndExecTime", DateTime(timezone=True)) Status = Column("Status", String(32), default="Received") MinorStatus = Column("MinorStatus", String(128), default="Unknown") ApplicationStatus = Column("ApplicationStatus", String(255), default="Unknown") @@ -140,7 +140,7 @@ class SiteMask(JobDBBase): __tablename__ = "SiteMask" Site = Column(String(64), primary_key=True) Status = Column(String(64)) - LastUpdateTime = Column(DateTime) + LastUpdateTime = Column(DateTime(timezone=True)) Author = Column(String(255)) Comment = Column(Text) @@ -148,7 +148,7 @@ class SiteMask(JobDBBase): class SiteMaskLogging(JobDBBase): __tablename__ = "SiteMaskLogging" Site = Column(String(64), primary_key=True) - UpdateTime = Column(DateTime, primary_key=True) + UpdateTime = Column(DateTime(timezone=True), primary_key=True) Status = Column(String(64)) Author = Column(String(255)) Comment = Column(Text) @@ -161,7 +161,7 @@ class HeartBeatLoggingInfo(JobDBBase): ) Name = Column(String(100), primary_key=True) Value = Column(Text) - HeartBeatTime = Column(DateTime, primary_key=True) + HeartBeatTime = Column(DateTime(timezone=True), primary_key=True) class JobCommands(JobDBBase): @@ -172,5 +172,5 @@ class JobCommands(JobDBBase): Command = Column(String(100)) Arguments = Column(String(100)) Status = Column(String(64), default="Received") - ReceptionTime = Column(DateTime, primary_key=True) - ExecutionTime = NullColumn(DateTime) + ReceptionTime = Column(DateTime(timezone=True), primary_key=True) + ExecutionTime = NullColumn(DateTime(timezone=True)) From 33048d70d94ffdba7bbbd7435090c785bdbf604c Mon Sep 17 00:00:00 2001 From: Jorge Lisa <64639359+AcquaDiGiorgio@users.noreply.github.com> Date: Wed, 25 Sep 2024 15:20:13 +0200 Subject: [PATCH 7/7] chore: Rename integration tests to fit the DB being used --- .github/workflows/main.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 27e01774..8f4f29db 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -76,6 +76,7 @@ jobs: uses: codecov/codecov-action@v4.5.0 pytest-integration: + name: Integration test - ${{ matrix.dbName }} runs-on: ubuntu-latest strategy: fail-fast: false @@ -98,7 +99,7 @@ jobs: pip install pytest-github-actions-annotate-failures pip install git+https://github.com/DIRACGrid/DIRAC.git@integration pip install ./diracx-core/[testing] ./diracx-api/[testing] ./diracx-cli/[testing] ./diracx-client/[testing] ./diracx-routers/[testing] ./diracx-db/[testing] ./diracx-testing/ - - name: Start demo using ${{ matrix.dbName }} + - name: Start demo run: | git clone -b diracx-issue-147-postgres-integration https://github.com/AcquaDiGiorgio/diracx-charts.git ../diracx-charts ../diracx-charts/run_demo.sh ${{ matrix.cliOption }} --enable-open-telemetry --enable-coverage --exit-when-done --set-value developer.autoReload=false --ci-values ../diracx-charts/demo/ci_values.yaml $PWD