diracx-db 0.0.1a15__py3-none-any.whl → 0.0.1a17__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- diracx/db/sql/jobs/db.py +32 -12
- diracx/db/sql/jobs/status_utility.py +2 -2
- diracx/db/sql/utils.py +4 -2
- {diracx_db-0.0.1a15.dist-info → diracx_db-0.0.1a17.dist-info}/METADATA +3 -3
- {diracx_db-0.0.1a15.dist-info → diracx_db-0.0.1a17.dist-info}/RECORD +8 -8
- {diracx_db-0.0.1a15.dist-info → diracx_db-0.0.1a17.dist-info}/WHEEL +0 -0
- {diracx_db-0.0.1a15.dist-info → diracx_db-0.0.1a17.dist-info}/entry_points.txt +0 -0
- {diracx_db-0.0.1a15.dist-info → diracx_db-0.0.1a17.dist-info}/top_level.txt +0 -0
diracx/db/sql/jobs/db.py
CHANGED
@@ -19,6 +19,9 @@ from diracx.core.models import (
|
|
19
19
|
LimitedJobStatusReturn,
|
20
20
|
ScalarSearchOperator,
|
21
21
|
ScalarSearchSpec,
|
22
|
+
SearchSpec,
|
23
|
+
SortDirection,
|
24
|
+
SortSpec,
|
22
25
|
)
|
23
26
|
from diracx.core.properties import JOB_SHARING, SecurityProperty
|
24
27
|
|
@@ -83,14 +86,14 @@ class JobDB(BaseSQLDB):
|
|
83
86
|
|
84
87
|
async def search(
|
85
88
|
self,
|
86
|
-
parameters,
|
87
|
-
search,
|
88
|
-
sorts,
|
89
|
+
parameters: list[str] | None,
|
90
|
+
search: list[SearchSpec],
|
91
|
+
sorts: list[SortSpec],
|
89
92
|
*,
|
90
93
|
distinct: bool = False,
|
91
94
|
per_page: int = 100,
|
92
95
|
page: int | None = None,
|
93
|
-
) -> list[dict[
|
96
|
+
) -> tuple[int, list[dict[Any, Any]]]:
|
94
97
|
# Find which columns to select
|
95
98
|
columns = _get_columns(Jobs.__table__, parameters)
|
96
99
|
stmt = select(*columns)
|
@@ -98,28 +101,45 @@ class JobDB(BaseSQLDB):
|
|
98
101
|
stmt = apply_search_filters(Jobs.__table__, stmt, search)
|
99
102
|
|
100
103
|
# Apply any sort constraints
|
104
|
+
sort_columns = []
|
101
105
|
for sort in sorts:
|
102
106
|
if sort["parameter"] not in Jobs.__table__.columns:
|
103
107
|
raise InvalidQueryError(
|
104
108
|
f"Cannot sort by {sort['parameter']}: unknown column"
|
105
109
|
)
|
106
110
|
column = Jobs.__table__.columns[sort["parameter"]]
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
+
sorted_column = None
|
112
|
+
if sort["direction"] == SortDirection.ASC:
|
113
|
+
sorted_column = column.asc()
|
114
|
+
elif sort["direction"] == SortDirection.DESC:
|
115
|
+
sorted_column = column.desc()
|
111
116
|
else:
|
112
117
|
raise InvalidQueryError(f"Unknown sort {sort['direction']=}")
|
118
|
+
sort_columns.append(sorted_column)
|
119
|
+
|
120
|
+
if sort_columns:
|
121
|
+
stmt = stmt.order_by(*sort_columns)
|
113
122
|
|
114
123
|
if distinct:
|
115
124
|
stmt = stmt.distinct()
|
116
125
|
|
126
|
+
# Calculate total count before applying pagination
|
127
|
+
total_count_subquery = stmt.alias()
|
128
|
+
total_count_stmt = select(func.count()).select_from(total_count_subquery)
|
129
|
+
total = (await self.conn.execute(total_count_stmt)).scalar_one()
|
130
|
+
|
117
131
|
# Apply pagination
|
118
|
-
if page:
|
119
|
-
|
132
|
+
if page is not None:
|
133
|
+
if page < 1:
|
134
|
+
raise InvalidQueryError("Page must be a positive integer")
|
135
|
+
if per_page < 1:
|
136
|
+
raise InvalidQueryError("Per page must be a positive integer")
|
137
|
+
stmt = stmt.offset((page - 1) * per_page).limit(per_page)
|
120
138
|
|
121
139
|
# Execute the query
|
122
|
-
return [
|
140
|
+
return total, [
|
141
|
+
dict(row._mapping) async for row in (await self.conn.stream(stmt))
|
142
|
+
]
|
123
143
|
|
124
144
|
async def _insertNewJDL(self, jdl) -> int:
|
125
145
|
from DIRAC.WorkloadManagementSystem.DB.JobDBUtils import compressJDL
|
@@ -314,7 +334,7 @@ class JobDB(BaseSQLDB):
|
|
314
334
|
from DIRAC.Core.Utilities.ClassAd.ClassAdLight import ClassAd
|
315
335
|
from DIRAC.Core.Utilities.ReturnValues import SErrorException
|
316
336
|
|
317
|
-
result = await self.search(
|
337
|
+
_, result = await self.search(
|
318
338
|
parameters=[
|
319
339
|
"Status",
|
320
340
|
"MinorStatus",
|
@@ -41,9 +41,9 @@ async def set_job_status(
|
|
41
41
|
# transform JobStateUpdate objects into dicts
|
42
42
|
statusDict = {}
|
43
43
|
for key, value in status.items():
|
44
|
-
statusDict[key] = {k: v for k, v in value.
|
44
|
+
statusDict[key] = {k: v for k, v in value.model_dump().items() if v is not None}
|
45
45
|
|
46
|
-
res = await job_db.search(
|
46
|
+
_, res = await job_db.search(
|
47
47
|
parameters=["Status", "StartExecTime", "EndExecTime"],
|
48
48
|
search=[
|
49
49
|
{
|
diracx/db/sql/utils.py
CHANGED
@@ -11,7 +11,7 @@ from datetime import datetime, timedelta, timezone
|
|
11
11
|
from functools import partial
|
12
12
|
from typing import TYPE_CHECKING, AsyncIterator, Self, cast
|
13
13
|
|
14
|
-
from pydantic import
|
14
|
+
from pydantic import TypeAdapter
|
15
15
|
from sqlalchemy import Column as RawColumn
|
16
16
|
from sqlalchemy import DateTime, Enum, MetaData, select
|
17
17
|
from sqlalchemy.exc import OperationalError
|
@@ -123,7 +123,9 @@ class BaseSQLDB(metaclass=ABCMeta):
|
|
123
123
|
if db_url == "sqlite+aiosqlite:///:memory:":
|
124
124
|
db_urls[db_name] = db_url
|
125
125
|
else:
|
126
|
-
db_urls[db_name] =
|
126
|
+
db_urls[db_name] = str(
|
127
|
+
TypeAdapter(SqlalchemyDsn).validate_python(db_url)
|
128
|
+
)
|
127
129
|
except Exception:
|
128
130
|
logger.error("Error loading URL for %s", db_name)
|
129
131
|
raise
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: diracx-db
|
3
|
-
Version: 0.0.
|
3
|
+
Version: 0.0.1a17
|
4
4
|
Summary: TODO
|
5
5
|
License: GPL-3.0-only
|
6
6
|
Classifier: Intended Audience :: Science/Research
|
@@ -14,8 +14,8 @@ Requires-Dist: dirac
|
|
14
14
|
Requires-Dist: diracx-core
|
15
15
|
Requires-Dist: fastapi
|
16
16
|
Requires-Dist: opensearch-py[async]
|
17
|
-
Requires-Dist: pydantic
|
18
|
-
Requires-Dist: sqlalchemy[aiomysql,aiosqlite]
|
17
|
+
Requires-Dist: pydantic >=2.4
|
18
|
+
Requires-Dist: sqlalchemy[aiomysql,aiosqlite] >=2
|
19
19
|
Provides-Extra: testing
|
20
20
|
Requires-Dist: diracx-testing ; extra == 'testing'
|
21
21
|
|
@@ -6,7 +6,7 @@ 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=mau0_2uRi-I3geefmKQRWFKo4JcIkIUADvnwBiQX700,9129
|
8
8
|
diracx/db/sql/__init__.py,sha256=R6tk5lo1EHbt8joGDesesYHcc1swIq9T4AaSixhh7lA,252
|
9
|
-
diracx/db/sql/utils.py,sha256=
|
9
|
+
diracx/db/sql/utils.py,sha256=F55qv4u5JQMV5Cl-CNq4nXRCODlCZWarM8Dnkrx55T8,7930
|
10
10
|
diracx/db/sql/auth/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
11
11
|
diracx/db/sql/auth/db.py,sha256=mKjy5B8orw0yu6nOwxyzbBqyeE-J9iYq6fKjuELmr9g,10273
|
12
12
|
diracx/db/sql/auth/schema.py,sha256=JCkSa2IRzqMHTpaSc9aB9h33XsFyEM_Ohsenex6xagY,2835
|
@@ -14,14 +14,14 @@ diracx/db/sql/dummy/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSu
|
|
14
14
|
diracx/db/sql/dummy/db.py,sha256=5PIPv6aKY7CGIwmvnGKowjVr9ZQWpbjFSd2PIX7YOUw,1627
|
15
15
|
diracx/db/sql/dummy/schema.py,sha256=uEkGDNVZbmJecytkHY1CO-M1MiKxe5w1_h0joJMPC9E,680
|
16
16
|
diracx/db/sql/jobs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
17
|
-
diracx/db/sql/jobs/db.py,sha256=
|
17
|
+
diracx/db/sql/jobs/db.py,sha256=CyQIPX2g5ancBIBEMLijAyTi5HZxTgeVH0qQZ3p3KcU,30722
|
18
18
|
diracx/db/sql/jobs/schema.py,sha256=YkxIdjTkvLlEZ9IQt86nj80eMvOPbcrfk9aisjmNpqY,9275
|
19
|
-
diracx/db/sql/jobs/status_utility.py,sha256=
|
19
|
+
diracx/db/sql/jobs/status_utility.py,sha256=w3caA9ng4y-Bzp0DOasj_DQ_M6JxAzJoHVmyJbEZ2qE,10534
|
20
20
|
diracx/db/sql/sandbox_metadata/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
21
21
|
diracx/db/sql/sandbox_metadata/db.py,sha256=0EDFMfOW_O3pEPTShqBCME9z4j-JKpyYM6-BBccr27E,6303
|
22
22
|
diracx/db/sql/sandbox_metadata/schema.py,sha256=rngYYkJxBhjETBHGLD1CTipDGe44mRYR0wdaFoAJwp0,1400
|
23
|
-
diracx_db-0.0.
|
24
|
-
diracx_db-0.0.
|
25
|
-
diracx_db-0.0.
|
26
|
-
diracx_db-0.0.
|
27
|
-
diracx_db-0.0.
|
23
|
+
diracx_db-0.0.1a17.dist-info/METADATA,sha256=NarGcFXcBgKbSaHiyBPBVRj7dJ4xQ7OpJ8k0oIA7cHI,691
|
24
|
+
diracx_db-0.0.1a17.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
25
|
+
diracx_db-0.0.1a17.dist-info/entry_points.txt,sha256=xEFGu_zgmPgQPlUeFtdahQfQIboJ1ugFOK8eMio9gtw,271
|
26
|
+
diracx_db-0.0.1a17.dist-info/top_level.txt,sha256=vJx10tdRlBX3rF2Psgk5jlwVGZNcL3m_7iQWwgPXt-U,7
|
27
|
+
diracx_db-0.0.1a17.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|