Skip to content

Commit

Permalink
Improvement of updating projects
Browse files Browse the repository at this point in the history
  • Loading branch information
khoroshevskyi committed Jan 11, 2024
1 parent d3010f7 commit 9105e9a
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 24 deletions.
2 changes: 1 addition & 1 deletion pepdbagent/modules/annotation.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
SUBMISSION_DATE_KEY,
LAST_UPDATE_DATE_KEY,
)
from pepdbagent.db_utils import BaseEngine, Projects, Views
from pepdbagent.db_utils import BaseEngine, Projects
from pepdbagent.exceptions import FilterError, ProjectNotFoundError, RegistryPathError
from pepdbagent.models import AnnotationList, AnnotationModel
from pepdbagent.utils import convert_date_string_to_date, registry_path_converter, tuple_converter
Expand Down
101 changes: 88 additions & 13 deletions pepdbagent/modules/project.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import datetime
import json
import logging
from typing import Union, List, NoReturn
from typing import Union, List, NoReturn, Mapping

import peppy
from sqlalchemy import and_, delete, select
Expand Down Expand Up @@ -90,11 +90,16 @@ def get(
subsample_list = list(subsample_dict.values())
else:
subsample_list = []

# samples
samples_dict = {
sample_sa.row_number: sample_sa.sample
for sample_sa in found_prj.samples_mapping
}

project_value = {
CONFIG_KEY: found_prj.config,
SAMPLE_RAW_DICT_KEY: [
sample_sa.sample for sample_sa in found_prj.samples_mapping
],
SAMPLE_RAW_DICT_KEY: [samples_dict[key] for key in sorted(samples_dict)],
SUBSAMPLE_RAW_LIST_KEY: subsample_list,
}
# project_value = found_prj.project_value
Expand Down Expand Up @@ -466,16 +471,25 @@ def update(
found_prj.name = found_prj.config[NAME_KEY]

if "samples" in update_dict:
if found_prj.samples_mapping:
for sample in found_prj.samples_mapping:
_LOGGER.debug(f"deleting samples: {str(sample)}")
session.delete(sample)

self._add_samples_to_project(
found_prj,
update_dict["samples"],
sample_table_index=update_dict["config"].get(SAMPLE_TABLE_INDEX_KEY),
self._update_samples(
namespace=namespace,
name=name,
tag=tag,
samples_list=update_dict["samples"],
sample_name_key=update_dict["config"].get(
SAMPLE_TABLE_INDEX_KEY, "sample_name"
),
)
# if found_prj.samples_mapping:
# for sample in found_prj.samples_mapping:
# _LOGGER.debug(f"deleting samples: {str(sample)}")
# session.delete(sample)
#
# self._add_samples_to_project(
# found_prj,
# update_dict["samples"],
# sample_table_index=update_dict["config"].get(SAMPLE_TABLE_INDEX_KEY),
# )

if "subsamples" in update_dict:
if found_prj.subsamples_mapping:
Expand All @@ -496,6 +510,67 @@ def update(
else:
raise ProjectNotFoundError("No items will be updated!")

def _update_samples(
self,
namespace: str,
name: str,
tag: str,
samples_list: List[Mapping],
sample_name_key: str = "sample_name",
) -> None:
"""
Update samples in the project
This is a new method that instead of deleting all samples and adding new ones,
updates samples and adds new ones if they don't exist
:param samples_list: list of samples to be updated
:param sample_name_key: key of the sample name
:return: None
"""
new_sample_names = [sample[sample_name_key] for sample in samples_list]
with Session(self._sa_engine) as session:
project = session.scalar(
select(Projects).where(
and_(
Projects.namespace == namespace, Projects.name == name, Projects.tag == tag
)
)
)
old_sample_names = [sample.sample_name for sample in project.samples_mapping]
for old_sample in old_sample_names:
if old_sample not in new_sample_names:
session.execute(
delete(Samples).where(
and_(
Samples.sample_name == old_sample, Samples.project_id == project.id
)
)
)

order_number = 0
for new_sample in samples_list:
order_number += 1
if new_sample[sample_name_key] not in old_sample_names:
project.samples_mapping.append(
Samples(
sample=new_sample,
sample_name=new_sample[sample_name_key],
row_number=order_number,
)
)
else:
sample_mapping = session.scalar(
select(Samples).where(
and_(
Samples.sample_name == new_sample[sample_name_key],
Samples.project_id == project.id,
)
)
)
sample_mapping.sample = new_sample
sample_mapping.row_number = order_number
session.commit()

@staticmethod
def __create_update_dict(update_values: UpdateItems) -> dict:
"""
Expand Down
12 changes: 6 additions & 6 deletions pepdbagent/modules/view.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,12 @@
DEFAULT_TAG,
PKG_NAME,
)
from pepdbagent.exceptions import ViewNotFoundError, SampleAlreadyInView, ProjectNotFoundError, SampleNotFoundError
from pepdbagent.exceptions import (
ViewNotFoundError,
SampleAlreadyInView,
ProjectNotFoundError,
SampleNotFoundError,
)

from pepdbagent.db_utils import BaseEngine, Samples, Projects, Views, ViewSampleAssociation
from pepdbagent.models import ViewAnnotation, CreateViewDictModel, ProjectViews
Expand Down Expand Up @@ -383,11 +388,6 @@ def get_views_annotation(
"""
statement = select(Views).where(
Views.project_mapping.has(namespace=namespace, name=name, tag=tag),
and_(
Projects.name == name,
Projects.namespace == namespace,
Projects.tag == tag,
),
)
views_list = []

Expand Down
7 changes: 3 additions & 4 deletions tests/test_pepagent.py
Original file line number Diff line number Diff line change
Expand Up @@ -324,9 +324,9 @@ def test_update_project_description(
"namespace, name",
[
["namespace1", "amendments1"],
["namespace1", "amendments2"],
["namespace2", "derive"],
["namespace2", "imply"],
# ["namespace1", "amendments2"],
# ["namespace2", "derive"],
# ["namespace2", "imply"],
],
)
def test_update_whole_project(self, initiate_pepdb_con, namespace, name):
Expand Down Expand Up @@ -1195,7 +1195,6 @@ def test_get_view_list_from_project(
"sample_list": [sample_name, "pig_1h"],
},
)
result = initiate_pepdb_con.view.get_views_annotation(namespace, name, "default")
assert (
len(initiate_pepdb_con.view.get_views_annotation(namespace, name, "default").views)
== 1
Expand Down

0 comments on commit 9105e9a

Please sign in to comment.