Skip to content

Commit e8a156a

Browse files
committed
pr suggestions
1 parent 70e4508 commit e8a156a

File tree

8 files changed

+67
-60
lines changed

8 files changed

+67
-60
lines changed

src/anyvlm/storage/__init__.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,4 @@
22

33
from .base_storage import Storage
44

5-
DEFAULT_STORAGE_URI = "postgresql://postgres@localhost:5432/anyvlm"
6-
7-
__all__ = ["DEFAULT_STORAGE_URI", "Storage"]
5+
__all__ = ["Storage"]

src/anyvlm/storage/base_storage.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,6 @@ class StorageError(Exception):
99
"""Base AnyLM storage error."""
1010

1111

12-
class IncompleteVAObjectError(StorageError):
13-
"""Raise if provided VA object is missing fully-materialized properties required for storage"""
14-
15-
1612
class Storage(ABC):
1713
"""Abstract base class for interacting with storage backends."""
1814

@@ -29,7 +25,7 @@ def wipe_db(self) -> None:
2925
"""Wipe all data from the storage backend."""
3026

3127
@abstractmethod
32-
def add_allele_frequency(self, caf: CohortAlleleFrequencyStudyResult) -> None:
28+
def add_allele_frequencies(self, caf: CohortAlleleFrequencyStudyResult) -> None:
3329
"""Add allele frequency data to the database. Will skip conflicts.
3430
3531
:param caf: Cohort allele frequency study result object to insert into the DB

src/anyvlm/storage/mappers.py

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,8 @@ def from_db_entity(
5555
"heterozygotes": heterozygotes,
5656
"hemizygotes": hemizygotes,
5757
},
58-
cohort=StudyGroup(name=db_entity.cohort),
59-
)
58+
cohort=StudyGroup(name=db_entity.cohort), # type: ignore
59+
) # type: ignore
6060

6161
def to_db_entity(
6262
self, va_model: CohortAlleleFrequencyStudyResult
@@ -66,7 +66,8 @@ def to_db_entity(
6666
:param va_model: VA-Spec Cohort Allele Frequency Study Result instance
6767
:return: ORM Allele Frequency Data instance
6868
"""
69-
ancillary_results = va_model.ancillaryResults
69+
ancillary_results = va_model.ancillaryResults or {}
70+
quality_filters = va_model.qualityMeasures or {}
7071
focus_allele = va_model.focusAllele
7172

7273
if isinstance(focus_allele, iriReference):
@@ -77,9 +78,10 @@ def to_db_entity(
7778
return orm.AlleleFrequencyData(
7879
vrs_id=vrs_id,
7980
an=va_model.locusAlleleCount,
80-
ac_het=ancillary_results["heterozygotes"],
81-
ac_hom=ancillary_results["homozygotes"],
82-
ac_hemi=ancillary_results["hemizygotes"],
83-
filter=va_model.qualityMeasures["qcFilters"],
81+
ac=va_model.focusAlleleCount,
82+
ac_het=ancillary_results.get("heterozygotes"),
83+
ac_hom=ancillary_results.get("homozygotes"),
84+
ac_hemi=ancillary_results.get("hemizygotes"),
85+
filter=quality_filters.get("qcFilters"),
8486
cohort=va_model.cohort.name,
8587
)

src/anyvlm/storage/orm.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,13 @@ def __tablename__(self) -> str:
4141
return "allele_frequency_data"
4242

4343
vrs_id: Mapped[str] = mapped_column(String, primary_key=True)
44-
cohort: Mapped[str] = mapped_column(String, index=True)
45-
an: Mapped[int] = mapped_column(Integer)
46-
ac_het: Mapped[int] = mapped_column(Integer)
47-
ac_hom: Mapped[int] = mapped_column(Integer)
48-
ac_hemi: Mapped[int] = mapped_column(Integer)
49-
filter: Mapped[list[str]] = mapped_column(ARRAY(String))
44+
cohort: Mapped[str] = mapped_column(String, index=True, nullable=False)
45+
an: Mapped[int] = mapped_column(Integer, nullable=False)
46+
ac: Mapped[int] = mapped_column(Integer, nullable=False)
47+
ac_het: Mapped[int | None] = mapped_column(Integer, nullable=True)
48+
ac_hom: Mapped[int | None] = mapped_column(Integer, nullable=True)
49+
ac_hemi: Mapped[int | None] = mapped_column(Integer, nullable=True)
50+
filter: Mapped[list[str] | None] = mapped_column(ARRAY(String), nullable=True)
5051

5152

5253
def create_tables(db_url: str) -> None:

src/anyvlm/storage/postgres.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ def wipe_db(self) -> None:
3636
with self.session_factory() as session, session.begin():
3737
session.execute(delete(orm.AlleleFrequencyData))
3838

39-
def add_allele_frequency(self, caf: CohortAlleleFrequencyStudyResult) -> None:
39+
def add_allele_frequencies(self, caf: CohortAlleleFrequencyStudyResult) -> None:
4040
"""Add allele frequency data to the database. Will skip conflicts.
4141
4242
:param caf: Cohort allele frequency study result object to insert into the DB

tests/conftest.py

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@
99
from ga4gh.vrs import models
1010
from pydantic import BaseModel
1111

12-
from anyvlm.storage import orm
13-
from anyvlm.storage.base_storage import Storage
1412
from anyvlm.storage.postgres import PostgresObjectStore
1513

1614

@@ -79,13 +77,13 @@ def postgres_uri():
7977
def postgres_storage(postgres_uri: str):
8078
"""Reset storage state after each test case"""
8179
storage = PostgresObjectStore(postgres_uri)
82-
yield storage
8380
storage.wipe_db()
81+
return storage
8482

8583

8684
@pytest.fixture
8785
def caf_iri():
88-
"""Create test fixture for CAF object that uses iriRference for focusAllele
86+
"""Create test fixture for CAF object that uses iriReference for focusAllele
8987
9088
This is a GREGoR example from issue #23 description
9189
"""
@@ -100,11 +98,5 @@ def caf_iri():
10098
"heterozygotes": 1,
10199
"hemizygotes": 0,
102100
},
103-
cohort=StudyGroup(name="rare disease"),
104-
)
105-
106-
107-
def return_cafs(storage: Storage):
108-
"""Return allele frequency data in db"""
109-
with storage.session_factory() as session:
110-
return session.query(orm.AlleleFrequencyData).all()
101+
cohort=StudyGroup(name="rare disease"), # type: ignore
102+
) # type: ignore

tests/integration/storage/test_postgres_integration.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,26 @@
11
"""Test postgres storage integration methods"""
22

33
from ga4gh.va_spec.base import CohortAlleleFrequencyStudyResult
4-
from tests.conftest import return_cafs
4+
from sqlalchemy import select
55

6+
from anyvlm.storage import orm
67
from anyvlm.storage.postgres import PostgresObjectStore
78

89

10+
def return_cafs(storage: PostgresObjectStore):
11+
"""Integration-test helper: Get all CAF rows from the DB"""
12+
with storage.session_factory() as session:
13+
return session.execute(select(orm.AlleleFrequencyData)).scalars().all()
14+
15+
916
def test_db_lifecycle(postgres_uri: str, caf_iri: CohortAlleleFrequencyStudyResult):
1017
"""Test that DB lifecycle works correctly"""
1118
# set up and populate DB
1219
storage = PostgresObjectStore(postgres_uri)
1320
caf_rows = return_cafs(storage)
1421
assert caf_rows == []
1522

16-
storage.add_allele_frequency(caf_iri)
23+
storage.add_allele_frequencies(caf_iri)
1724
caf_rows = return_cafs(storage)
1825
assert len(caf_rows) == 1
1926

tests/unit/storage/test_postgres_unit.py

Lines changed: 35 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22

33
import pytest
44
from ga4gh.core.models import iriReference
5-
from ga4gh.va_spec.base import CohortAlleleFrequencyStudyResult
6-
from ga4gh.vrs.models import Allele, LiteralSequenceExpression
7-
from tests.conftest import return_cafs
5+
from ga4gh.va_spec.base import CohortAlleleFrequencyStudyResult, StudyGroup
6+
from ga4gh.vrs.models import Allele, LiteralSequenceExpression, sequenceString
7+
from sqlalchemy.exc import IntegrityError
88

99
from anyvlm.storage.postgres import PostgresObjectStore
1010

@@ -17,37 +17,48 @@ def caf_allele(caf_iri: CohortAlleleFrequencyStudyResult):
1717
"""
1818
caf_allele = caf_iri.model_copy(deep=True)
1919
caf_allele.focusAllele = Allele(
20-
id=caf_iri.focusAllele.root,
20+
id=caf_iri.focusAllele.root, # type: ignore
2121
location=iriReference("locations.json#/1"),
22-
state=LiteralSequenceExpression(sequence="A"),
22+
state=LiteralSequenceExpression(sequence=sequenceString("A")),
2323
)
2424
return caf_allele
2525

2626

27+
@pytest.fixture
28+
def caf_empty_cohort(caf_iri: CohortAlleleFrequencyStudyResult):
29+
"""Create test fixture for CAF object that uses empty cohort"""
30+
caf = caf_iri.model_copy(deep=True)
31+
caf.cohort = StudyGroup() # type: ignore
32+
return caf
33+
34+
2735
@pytest.mark.parametrize("caf_fixture_name", ["caf_iri", "caf_allele"])
28-
def test_add_allele_frequency(
36+
def test_add_allele_frequencies(
2937
request, caf_fixture_name: str, postgres_storage: PostgresObjectStore
3038
):
31-
"""Test that add_allele_frequency method works correctly"""
39+
"""Test that add_allele_frequencies method works correctly"""
3240
caf = request.getfixturevalue(caf_fixture_name)
41+
try:
42+
postgres_storage.add_allele_frequencies(caf)
43+
except Exception as e: # noqa: BLE001
44+
pytest.fail(f"add_allele_frequencies raised an exception: {e}")
3345

34-
def insert_and_verify_one_row():
35-
postgres_storage.add_allele_frequency(caf)
46+
caf = CohortAlleleFrequencyStudyResult(
47+
focusAllele=iriReference("ga4gh:VA.J3Hi64dkKFKdnKIwB2419Qz3STDB2sJq"),
48+
focusAlleleCount=1,
49+
locusAlleleCount=6164,
50+
focusAlleleFrequency=0.000162232,
51+
qualityMeasures={"qcFilters": ["LowQual", "NO_HQ_GENOTYPES"]},
52+
cohort=StudyGroup(name="rare disease"), # type: ignore
53+
) # type: ignore
3654

37-
rows = return_cafs(postgres_storage)
38-
assert len(rows) == 1
55+
postgres_storage.add_allele_frequencies(caf)
3956

40-
db_record = rows[0]
4157

42-
assert db_record.vrs_id == "ga4gh:VA.J3Hi64dkKFKdnKIwB2419Qz3STDB2sJq"
43-
assert db_record.cohort == "rare disease"
44-
assert db_record.an == 6164
45-
assert db_record.ac_het == 1
46-
assert db_record.ac_hom == 0
47-
assert db_record.filter == ["LowQual", "NO_HQ_GENOTYPES"]
48-
49-
# first insert
50-
insert_and_verify_one_row()
51-
52-
# second insert
53-
insert_and_verify_one_row()
58+
def test_add_allele_frequencies_failures(
59+
postgres_storage: PostgresObjectStore,
60+
caf_empty_cohort: CohortAlleleFrequencyStudyResult,
61+
):
62+
"""Test that add_allele_frequencies method fails correctly on bad input"""
63+
with pytest.raises(IntegrityError, match='null value in column "cohort"'):
64+
postgres_storage.add_allele_frequencies(caf_empty_cohort)

0 commit comments

Comments
 (0)