Skip to content

Commit 88f91f5

Browse files
fix: improve listing
1 parent 9dfe2df commit 88f91f5

File tree

6 files changed

+32
-58
lines changed

6 files changed

+32
-58
lines changed

packages/postgres-database/src/simcore_postgres_database/utils_projects_nodes.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ def model_dump_as_node(self) -> dict[str, Any]:
116116
)
117117

118118

119-
def create_workbench_subquery() -> Subquery:
119+
def create_workbench_subquery(project_id: str) -> Subquery:
120120
return (
121121
sa.select(
122122
projects_nodes.c.project_uuid,
@@ -163,6 +163,7 @@ def create_workbench_subquery() -> Subquery:
163163
projects, projects_nodes.c.project_uuid == projects.c.uuid
164164
)
165165
)
166+
.where(projects.c.uuid == project_id)
166167
.group_by(projects_nodes.c.project_uuid)
167168
.subquery()
168169
)

services/director-v2/src/simcore_service_director_v2/modules/db/repositories/projects.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919
class ProjectsRepository(BaseRepository):
2020
async def get_project(self, project_id: ProjectID) -> ProjectAtDB:
21-
workbench_subquery = create_workbench_subquery()
21+
workbench_subquery = create_workbench_subquery(f"{project_id}")
2222

2323
async with self.db_engine.connect() as conn:
2424
query = (

services/web/server/src/simcore_service_webserver/projects/_jobs_repository.py

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,12 @@
44
from models_library.products import ProductName
55
from models_library.projects import ProjectID
66
from models_library.users import UserID
7-
from pydantic import TypeAdapter
87
from simcore_postgres_database.models.groups import user_to_groups
98
from simcore_postgres_database.models.project_to_groups import project_to_groups
109
from simcore_postgres_database.models.projects import projects
1110
from simcore_postgres_database.models.projects_metadata import projects_metadata
1211
from simcore_postgres_database.models.projects_to_jobs import projects_to_jobs
1312
from simcore_postgres_database.models.projects_to_products import projects_to_products
14-
from simcore_postgres_database.utils_projects_nodes import create_workbench_subquery
1513
from simcore_postgres_database.utils_repos import (
1614
get_columns_from_db_model,
1715
pass_or_acquire_connection,
@@ -20,6 +18,8 @@
2018
from sqlalchemy.dialects.postgresql import insert as pg_insert
2119
from sqlalchemy.ext.asyncio import AsyncConnection
2220

21+
from simcore_service_webserver.projects._projects_repository_legacy_utils import get_project_workbench
22+
2323
from ..db.base_repository import BaseRepository
2424
from .models import ProjectDBGet, ProjectJobDBGet
2525

@@ -170,25 +170,16 @@ async def list_projects_marked_as_jobs(
170170
# Step 5: Query to get the total count
171171
total_query = sa.select(sa.func.count()).select_from(base_query)
172172

173-
# Step 6: Create subquery to aggregate project nodes into workbench structure
174-
workbench_subquery = create_workbench_subquery()
175-
176-
# Step 7: Query to get the paginated list with full selection
173+
# Step 6: Query to get the paginated list with full selection
177174
list_query = (
178175
sa.select(
179176
*_PROJECT_DB_COLS,
180-
sa.func.coalesce(
181-
workbench_subquery.c.workbench, sa.text("'{}'::json")
182-
).label("workbench"),
183177
base_query.c.job_parent_resource_name,
184178
)
185179
.select_from(
186180
base_query.join(
187181
projects,
188182
projects.c.uuid == base_query.c.project_uuid,
189-
).outerjoin(
190-
workbench_subquery,
191-
projects.c.uuid == workbench_subquery.c.project_uuid,
192183
)
193184
)
194185
.order_by(
@@ -204,9 +195,9 @@ async def list_projects_marked_as_jobs(
204195
total_count = await conn.scalar(total_query)
205196
assert isinstance(total_count, int) # nosec
206197

207-
result = await conn.execute(list_query)
208-
projects_list = TypeAdapter(list[ProjectJobDBGet]).validate_python(
209-
result.fetchall()
210-
)
198+
projects_list = []
199+
async for project_row in await conn.stream(list_query):
200+
workbench = await get_project_workbench(conn, project_row.uuid)
201+
projects_list.append(ProjectJobDBGet.model_validate({**project_row, "workbench": workbench}))
211202

212203
return total_count, projects_list

services/web/server/src/simcore_service_webserver/projects/_projects_repository.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ async def get_project_with_workbench(
143143
project_uuid: ProjectID,
144144
) -> ProjectWithWorkbenchDBGet:
145145
async with pass_or_acquire_connection(get_asyncpg_engine(app), connection) as conn:
146-
workbench_subquery = create_workbench_subquery()
146+
workbench_subquery = create_workbench_subquery(f"{project_uuid}")
147147
query = (
148148
sql.select(
149149
*PROJECT_DB_COLS,

services/web/server/src/simcore_service_webserver/projects/_projects_repository_legacy.py

Lines changed: 2 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,6 @@
6060
ProjectNode,
6161
ProjectNodeCreate,
6262
ProjectNodesRepo,
63-
create_workbench_subquery,
6463
)
6564
from simcore_postgres_database.webserver_models import (
6665
ProjectType,
@@ -96,6 +95,7 @@
9695
convert_to_schema_names,
9796
create_project_access_rights,
9897
patch_workbench,
98+
get_project_workbench
9999
)
100100
from ._socketio_service import notify_project_document_updated
101101
from .exceptions import (
@@ -395,14 +395,9 @@ def _create_private_workspace_query(
395395
.group_by(project_to_groups.c.project_uuid)
396396
).subquery("my_access_rights_subquery")
397397

398-
workbench_subquery = create_workbench_subquery()
399-
400398
private_workspace_query = (
401399
sa.select(
402400
*PROJECT_DB_COLS,
403-
sa.func.coalesce(
404-
workbench_subquery.c.workbench, sa.text("'{}'::json")
405-
).label("workbench"),
406401
projects_to_products.c.product_name,
407402
projects_to_folders.c.folder_id,
408403
)
@@ -417,10 +412,6 @@ def _create_private_workspace_query(
417412
),
418413
isouter=True,
419414
)
420-
.outerjoin(
421-
workbench_subquery,
422-
workbench_subquery.c.project_uuid == projects.c.uuid,
423-
)
424415
)
425416
.where(
426417
(projects.c.workspace_id.is_(None)) # <-- Private workspace
@@ -462,14 +453,9 @@ def _create_shared_workspace_query(
462453
.group_by(workspaces_access_rights.c.workspace_id)
463454
).subquery("my_workspace_access_rights_subquery")
464455

465-
workbench_subquery = create_workbench_subquery()
466-
467456
shared_workspace_query = (
468457
sa.select(
469458
*PROJECT_DB_COLS,
470-
sa.func.coalesce(
471-
workbench_subquery.c.workbench, sa.text("'{}'::json")
472-
).label("workbench"),
473459
projects_to_products.c.product_name,
474460
projects_to_folders.c.folder_id,
475461
)
@@ -488,10 +474,6 @@ def _create_shared_workspace_query(
488474
),
489475
isouter=True,
490476
)
491-
.outerjoin(
492-
workbench_subquery,
493-
workbench_subquery.c.project_uuid == projects.c.uuid,
494-
)
495477
)
496478
.where(projects_to_products.c.product_name == product_name)
497479
)
@@ -698,7 +680,7 @@ async def list_projects_dicts( # pylint: disable=too-many-arguments,too-many-st
698680
# with the frontend. The frontend would need to check and adapt how it handles default values in
699681
# Workbench nodes, which are currently not returned if not set in the DB.
700682
prj_dict = dict(row.items()) | {
701-
"workbench": await self._get_workbench(conn, row.uuid),
683+
"workbench": await get_project_workbench(conn, row.uuid),
702684
}
703685
ProjectListAtDB.model_validate(prj_dict)
704686
prjs_output.append(prj_dict)

services/web/server/src/simcore_service_webserver/projects/_projects_repository_legacy_utils.py

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -191,23 +191,6 @@ async def _upsert_tags_in_project(
191191
.on_conflict_do_nothing()
192192
)
193193

194-
@staticmethod
195-
async def _get_workbench(
196-
connection: SAConnection,
197-
project_uuid: str,
198-
) -> dict[str, Any]:
199-
project_nodes_repo = ProjectNodesRepo(project_uuid=ProjectID(project_uuid))
200-
exclude_fields = {"node_id", "required_resources", "created", "modified"}
201-
workbench: dict[str, Any] = {}
202-
203-
project_nodes = await project_nodes_repo.list(connection) # type: ignore
204-
for project_node in project_nodes:
205-
node_data = project_node.model_dump(
206-
exclude=exclude_fields, exclude_none=True, exclude_unset=True
207-
)
208-
workbench[f"{project_node.node_id}"] = node_data
209-
return workbench
210-
211194
async def _get_project(
212195
self,
213196
connection: SAConnection,
@@ -238,11 +221,11 @@ async def _get_project(
238221
),
239222
).label("access_rights"),
240223
)
241-
.where(project_to_groups.c.project_uuid == f"{project_uuid}")
224+
.where(project_to_groups.c.project_uuid == project_uuid)
242225
.group_by(project_to_groups.c.project_uuid)
243226
).subquery("access_rights_subquery")
244227

245-
workbench_subquery = create_workbench_subquery()
228+
workbench_subquery = create_workbench_subquery(project_uuid)
246229

247230
query = (
248231
sa.select(
@@ -393,3 +376,20 @@ def patch_workbench(
393376
# patch
394377
current_node_data.update(new_node_data)
395378
return (patched_project, changed_entries)
379+
380+
381+
async def get_project_workbench(
382+
connection: SAConnection,
383+
project_uuid: str,
384+
) -> dict[str, Any]:
385+
project_nodes_repo = ProjectNodesRepo(project_uuid=ProjectID(project_uuid))
386+
exclude_fields = {"node_id", "required_resources", "created", "modified"}
387+
workbench: dict[str, Any] = {}
388+
389+
project_nodes = await project_nodes_repo.list(connection) # type: ignore
390+
for project_node in project_nodes:
391+
node_data = project_node.model_dump(
392+
exclude=exclude_fields, exclude_none=True, exclude_unset=True
393+
)
394+
workbench[f"{project_node.node_id}"] = node_data
395+
return workbench

0 commit comments

Comments
 (0)