Skip to content

Commit 8a11e5e

Browse files
authored
feat!: use materialized view for tx-exon alignment lookup (#462)
close #461 * Use the equivalent materialized view for this lookup. It's a small speedup but it only took a few minutes to fix (I think the view just exists as a referent for building the materialized view) * Rename methods regarding "tx_exon_aln_v" to just "tx_exon_aln", since the Python user doesn't really care that it's a view or a materialized view or whatever, they just need the "tx-exon aln" part. Hopefully this isn't too annoying to change wherever else it's used but if it is, this part could be walked back
1 parent c077a15 commit 8a11e5e

4 files changed

Lines changed: 40 additions & 38 deletions

File tree

src/cool_seq_tool/mappers/exon_genomic_coords.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -639,7 +639,7 @@ async def _get_all_exon_coords(
639639
if genomic_ac:
640640
query = f"""
641641
SELECT DISTINCT ord, tx_start_i, tx_end_i, alt_start_i, alt_end_i, alt_strand
642-
FROM {self.uta_db.schema}.tx_exon_aln_v
642+
FROM {self.uta_db.schema}.tx_exon_aln_mv
643643
WHERE tx_ac = '{tx_ac}'
644644
AND alt_aln_method = 'splign'
645645
AND alt_ac = '{genomic_ac}'
@@ -648,7 +648,7 @@ async def _get_all_exon_coords(
648648
else:
649649
query = f"""
650650
SELECT DISTINCT ord, tx_start_i, tx_end_i, alt_start_i, alt_end_i, alt_strand
651-
FROM {self.uta_db.schema}.tx_exon_aln_v as t
651+
FROM {self.uta_db.schema}.tx_exon_aln_mv as t
652652
INNER JOIN {self.uta_db.schema}._seq_anno_most_recent as s
653653
ON t.alt_ac = s.ac
654654
WHERE s.descr = ''
@@ -890,7 +890,7 @@ async def _genomic_to_tx_segment(
890890
# Run if gene is for a noncoding transcript
891891
query = f"""
892892
SELECT DISTINCT tx_ac
893-
FROM {self.uta_db.schema}.tx_exon_aln_v
893+
FROM {self.uta_db.schema}.tx_exon_aln_mv
894894
WHERE hgnc = '{gene}'
895895
AND alt_ac = '{genomic_ac}'
896896
""" # noqa: S608
@@ -955,7 +955,7 @@ async def _genomic_to_tx_segment(
955955
)
956956
else:
957957
is_exonic = True
958-
exon_data = await self.uta_db.get_tx_exon_aln_v_data(
958+
exon_data = await self.uta_db.get_tx_exon_aln_data(
959959
transcript,
960960
genomic_pos,
961961
genomic_pos,
@@ -1035,7 +1035,7 @@ async def _validate_genomic_breakpoint(
10351035
SELECT
10361036
MIN(alt_start_i) AS min_start,
10371037
MAX(alt_end_i) AS max_end
1038-
FROM {self.uta_db.schema}.tx_exon_aln_v
1038+
FROM {self.uta_db.schema}.tx_exon_aln_mv
10391039
WHERE tx_ac = '{tx_ac}'
10401040
AND alt_ac = '{genomic_ac}'
10411041
)
@@ -1060,7 +1060,7 @@ async def _get_tx_ac_gene(
10601060
"""
10611061
query = f"""
10621062
SELECT DISTINCT hgnc
1063-
FROM {self.uta_db.schema}.tx_exon_aln_v
1063+
FROM {self.uta_db.schema}.tx_exon_aln_mv
10641064
WHERE tx_ac = '{tx_ac}'
10651065
ORDER BY hgnc
10661066
LIMIT 1;

src/cool_seq_tool/mappers/mane_transcript.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ async def _liftover_to_38(self, genomic_tx_data: GenomicTxMetadata) -> None:
234234

235235
query = f"""
236236
SELECT DISTINCT alt_ac
237-
FROM {self.uta_db.schema}.tx_exon_aln_v
237+
FROM {self.uta_db.schema}.tx_exon_aln_mv
238238
WHERE tx_ac = '{genomic_tx_data.tx_ac}';
239239
""" # noqa: S608
240240
nc_acs = await self.uta_db.execute_query(query)
@@ -462,15 +462,15 @@ async def _g_to_c(
462462
:param ensembl_c_ac: Ensembl transcript accession
463463
:param alt_ac: Genomic accession
464464
:param found_result: ``True`` if found result, so do not need to query
465-
tx_exon_aln_v table. This is because the user did not need to liftover.
466-
``False`` if need to get result from tx_exon_aln_v table.
465+
tx_exon_aln_mv table. This is because the user did not need to liftover.
466+
``False`` if need to get result from tx_exon_aln_mv table.
467467
:return: Transcript data
468468
"""
469469
if found_result:
470470
tx_g_pos = g.alt_pos_range
471471
tx_pos_range = g.tx_pos_range
472472
else:
473-
result = await self.uta_db.get_tx_exon_aln_v_data(
473+
result = await self.uta_db.get_tx_exon_aln_data(
474474
refseq_c_ac,
475475
g.alt_pos_change_range[0],
476476
g.alt_pos_change_range[1],
@@ -820,7 +820,7 @@ def _get_protein_rep(
820820
if alt_ac is None:
821821
alt_ac = row["alt_ac"]
822822

823-
found_tx_exon_aln_v_result = False
823+
found_tx_exon_aln_result = False
824824
if is_p_or_c_start_anno:
825825
# Go from c -> g annotation (liftover as well)
826826
g = await self._c_to_g(tx_ac, (c_start_pos, c_end_pos))
@@ -832,7 +832,7 @@ def _get_protein_rep(
832832
annotation_layer=AnnotationLayer.GENOMIC,
833833
alt_ac=alt_ac,
834834
)
835-
found_tx_exon_aln_v_result = True
835+
found_tx_exon_aln_result = True
836836
if not g:
837837
continue
838838

@@ -842,7 +842,7 @@ def _get_protein_rep(
842842
g=g,
843843
refseq_c_ac=tx_ac,
844844
status=TranscriptPriority.LONGEST_COMPATIBLE_REMAINING,
845-
found_result=found_tx_exon_aln_v_result,
845+
found_result=found_tx_exon_aln_result,
846846
)
847847

848848
if not lcr_c_data:

src/cool_seq_tool/sources/uta_database.py

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ class DbConnectionArgs(BaseModelForbidExtra):
4444

4545

4646
class GenomicAlnData(BaseModelForbidExtra):
47-
"""Represent genomic alignment data from UTA tx_exon_aln_v view"""
47+
"""Represent genomic alignment data from UTA tx_exon_aln_mv view"""
4848

4949
hgnc: StrictStr = Field(..., description="HGNC gene symbol.")
5050
ord: StrictInt = Field(..., description="Exon number. 0-based.")
@@ -61,7 +61,7 @@ class GenomicAlnData(BaseModelForbidExtra):
6161

6262

6363
class TxExonAlnData(GenomicAlnData):
64-
"""Represent data from UTA tx_exon_aln_v view"""
64+
"""Represent data from UTA tx_exon_aln_mv view"""
6565

6666
tx_ac: StrictStr = Field(..., description="Transcript accession.")
6767
tx_start_i: StrictInt = Field(
@@ -285,7 +285,7 @@ async def get_alt_ac_start_or_end(
285285
query = f"""
286286
SELECT T.hgnc, T.alt_ac, T.alt_start_i, T.alt_end_i, T.alt_strand, T.ord
287287
FROM {self.schema}._cds_exons_fp_v as C
288-
JOIN {self.schema}.tx_exon_aln_v as T ON T.tx_ac = C.tx_ac
288+
JOIN {self.schema}.tx_exon_aln_mv as T ON T.tx_ac = C.tx_ac
289289
WHERE T.tx_ac = '{tx_ac}'
290290
{gene_query}
291291
AND {tx_exon_start} BETWEEN T.tx_start_i AND T.tx_end_i
@@ -394,15 +394,15 @@ async def gene_exists(self, gene: str) -> bool:
394394
return result[0][0]
395395

396396
async def transcript_exists(self, transcript: str) -> bool:
397-
"""Return whether or not a transcript exists in the UTA ``tx_exon_aln_v`` table
397+
"""Return whether or not a transcript exists in the UTA ``tx_exon_aln_mv`` table
398398
399399
:param transcript: A transcript accession
400400
:return: ``True`` if transcript exists in UTA, ``False`` if not
401401
"""
402402
query = f"""
403403
SELECT EXISTS(
404404
SELECT tx_ac
405-
FROM {self.schema}.tx_exon_aln_v
405+
FROM {self.schema}.tx_exon_aln_mv
406406
WHERE tx_ac = '{transcript}'
407407
);
408408
""" # noqa: S608
@@ -439,7 +439,7 @@ async def get_ac_descr(self, ac: str) -> str | None:
439439
result = None
440440
return result
441441

442-
async def get_tx_exon_aln_v_data(
442+
async def get_tx_exon_aln_data(
443443
self,
444444
tx_ac: str,
445445
start_pos: int,
@@ -448,7 +448,9 @@ async def get_tx_exon_aln_v_data(
448448
use_tx_pos: bool = True,
449449
like_tx_ac: bool = False,
450450
) -> list[TxExonAlnData]:
451-
"""Return queried data from tx_exon_aln_v table.
451+
"""Get alignments between exons and reference sequences.
452+
453+
This is a direct query against the UTA ``tx_exon_aln_mv`` view.
452454
453455
:param tx_ac: accession on c. coordinate
454456
:param start_pos: Start position change
@@ -491,7 +493,7 @@ async def get_tx_exon_aln_v_data(
491493
query = f"""
492494
SELECT hgnc, tx_ac, tx_start_i, tx_end_i, alt_ac, alt_start_i,
493495
alt_end_i, alt_strand, alt_aln_method, ord, tx_exon_id, alt_exon_id
494-
FROM {self.schema}.tx_exon_aln_v
496+
FROM {self.schema}.tx_exon_aln_mv
495497
{tx_q}
496498
{alt_ac_q}
497499
{aln_method}
@@ -543,7 +545,7 @@ async def get_mane_c_genomic_data(
543545
self, ac: str, alt_ac: str | None, start_pos: int, end_pos: int
544546
) -> GenomicTxMetadata | None:
545547
"""Get MANE transcript and genomic data. Used when going from g. to MANE c.
546-
representation. This function parses queried data from the tx_exon_aln_v
548+
representation. This function parses queried data from the tx_exon_aln_mv
547549
table, and sorts the queried data by the most recent genomic build
548550
549551
>>> import asyncio
@@ -569,7 +571,7 @@ async def get_mane_c_genomic_data(
569571
:return: Metadata for MANE genomic and transcript accessions results if
570572
successful
571573
"""
572-
results = await self.get_tx_exon_aln_v_data(
574+
results = await self.get_tx_exon_aln_data(
573575
tx_ac=ac,
574576
start_pos=start_pos,
575577
end_pos=end_pos,
@@ -636,7 +638,7 @@ async def get_genomic_tx_data(
636638
If ``alt_ac`` is provided, it will return the associated assembly.
637639
:return: Metadata for genomic and transcript accessions
638640
"""
639-
results = await self.get_tx_exon_aln_v_data(
641+
results = await self.get_tx_exon_aln_data(
640642
tx_ac,
641643
pos[0],
642644
pos[1],
@@ -816,7 +818,7 @@ async def get_transcripts(
816818
SELECT AA.pro_ac, AA.tx_ac, ALIGN.alt_ac, T.cds_start_i
817819
FROM {self.schema}.associated_accessions as AA
818820
JOIN {self.schema}.transcript as T ON T.ac = AA.tx_ac
819-
JOIN {self.schema}.tx_exon_aln_v as ALIGN ON T.ac = ALIGN.tx_ac
821+
JOIN {self.schema}.tx_exon_aln_mv as ALIGN ON T.ac = ALIGN.tx_ac
820822
WHERE ALIGN.alt_aln_method = 'splign'
821823
{gene_cond}
822824
{alt_ac_cond}
@@ -903,7 +905,7 @@ async def get_transcripts_from_genomic_pos(
903905
"""
904906
query = f"""
905907
SELECT distinct tx_ac
906-
FROM {self.schema}.tx_exon_aln_v
908+
FROM {self.schema}.tx_exon_aln_mv
907909
WHERE alt_ac = '{alt_ac}'
908910
AND {g_pos} BETWEEN alt_start_i AND alt_end_i
909911
AND tx_ac LIKE 'NM_%';

tests/sources/test_uta_database.py

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@
1414

1515

1616
@pytest.fixture(scope="module")
17-
def tx_exon_aln_v_data():
18-
"""Create test fixture for tx_aln_v_data test."""
17+
def tx_exon_aln_data():
18+
"""Create test fixture for tx_exon_aln_data test."""
1919
return TxExonAlnData(
2020
hgnc="BRAF",
2121
ord=14,
@@ -121,19 +121,19 @@ async def test_get_ac_descr(test_db):
121121

122122

123123
@pytest.mark.asyncio
124-
async def test_get_tx_exon_aln_v_data(test_db, tx_exon_aln_v_data):
125-
"""Test that get_tx_exon_aln_v_data"""
126-
resp = await test_db.get_tx_exon_aln_v_data(
124+
async def test_get_tx_exon_aln_data(test_db, tx_exon_aln_data):
125+
"""Test that get_tx_exon_aln_data"""
126+
resp = await test_db.get_tx_exon_aln_data(
127127
"NM_004333.4", 140453136, 140453136, alt_ac="NC_000007.13", use_tx_pos=False
128128
)
129-
assert resp == [tx_exon_aln_v_data]
129+
assert resp == [tx_exon_aln_data]
130130

131-
resp = await test_db.get_tx_exon_aln_v_data(
131+
resp = await test_db.get_tx_exon_aln_data(
132132
"NM_004333.4", 140453136, 140453136, alt_ac=None, use_tx_pos=False
133133
)
134-
assert resp == [tx_exon_aln_v_data]
134+
assert resp == [tx_exon_aln_data]
135135

136-
resp = await test_db.get_tx_exon_aln_v_data(
136+
resp = await test_db.get_tx_exon_aln_data(
137137
"NM_004333.4", 1860, 1860, alt_ac=None, use_tx_pos=True
138138
)
139139
assert resp == [
@@ -169,9 +169,9 @@ async def test_get_tx_exon_aln_v_data(test_db, tx_exon_aln_v_data):
169169

170170

171171
@pytest.mark.asyncio
172-
async def test_data_from_result(test_db, tx_exon_aln_v_data, data_from_result):
172+
async def test_data_from_result(test_db, tx_exon_aln_data, data_from_result):
173173
"""Test that data_from_result works correctly."""
174-
resp = test_db.data_from_result(tx_exon_aln_v_data)
174+
resp = test_db.data_from_result(tx_exon_aln_data)
175175
assert resp == data_from_result
176176

177177

@@ -198,7 +198,7 @@ async def test_mane_c_genomic_data(test_db):
198198
}
199199
assert resp == GenomicTxMetadata(**expected_params)
200200

201-
# Test example where sorting of tx_exon_aln_v is needed
201+
# Test example where sorting of tx_exon_aln_mv is needed
202202
resp = await test_db.get_mane_c_genomic_data(
203203
"NM_000077.5", "NC_000009.12", 21971186, 21971187
204204
)

0 commit comments

Comments
 (0)