22from markupsafe import escape
33from api import db
44from api .utils .bar_utils import BARUtils
5- from api .models .gaia import Aliases
6- from sqlalchemy import func
5+ from api .models .gaia import Genes , Aliases
6+ from sqlalchemy import func , or_
77import json
88
99gaia = Namespace ("Gaia" , description = "Gaia" , path = "/gaia" )
@@ -18,23 +18,51 @@ def get(self, identifier=""):
1818 identifier = escape (identifier )
1919
2020 # Is it valid
21- if BARUtils .is_alphanumeric (identifier ):
22- # Convert to json
23- identifier_json = json .dumps ([identifier ])
24-
25- # Get data
26- # Note: SQLAlchmemy or_ did not work here. Query had AND for some reason.
27- query = db .select (Aliases ).filter (
28- (func .json_contains (func .lower (Aliases .data ), func .lower (identifier_json ), "$.aliases" ))
29- | (func .json_extract (func .lower (Aliases .data ), "$.geneid" ) == func .lower (identifier ))
30- | (func .json_extract (func .lower (Aliases .data ), "$.locus" ) == func .lower (identifier )),
31- )
32- row = db .session .execute (query ).scalars ().first ()
21+ if BARUtils .is_gaia_alias (identifier ):
22+
23+ # Check if alias exists
24+ # Note: This check can be done in on query, but optimizer is not using indexes for some reason
25+ # Also, GAIA only uses the first result
26+ query = db .select (Aliases .genes_id , Aliases .alias ).filter (Aliases .alias == identifier )
27+ row = db .session .execute (query ).fetchone ()
3328
3429 if row :
35- return BARUtils .success_exit (row .data )
30+ # Alias exists. Get the genes_id
31+ query_id = row .genes_id
32+
33+ else :
34+ # Alias doesn't exist. Get the genes_id if it's locus or ncbi id
35+ query = db .select (Genes .id ).filter (or_ (Genes .locus == identifier , Genes .geneid == identifier ))
36+ row = db .session .execute (query ).fetchone ()
37+
38+ if row :
39+ query_id = row .id
40+ else :
41+ return BARUtils .error_exit ("Nothing found" ), 404
42+
43+ # Left join is important in case aliases do not exist for the given locus / geneid
44+ query = (
45+ db .select (Genes .species , Genes .locus , Genes .geneid , func .json_arrayagg (Aliases .alias ).label ("aliases" ))
46+ .select_from (Genes )
47+ .outerjoin (Aliases , Aliases .genes_id == Genes .id )
48+ .filter (Genes .id == query_id )
49+ )
50+
51+ result = db .session .execute (query ).fetchone ()
52+
53+ # See if aliases exists
54+ if result .aliases :
55+ aliases = json .loads (result .aliases )
3656 else :
37- return BARUtils .error_exit ("Nothing found" ), 404
57+ aliases = []
58+
59+ data = {
60+ "species" : result .species ,
61+ "locus" : result .locus ,
62+ "geneid" : result .geneid ,
63+ "aliases" : aliases ,
64+ }
65+ return BARUtils .success_exit (data )
3866
3967 else :
4068 return BARUtils .error_exit ("Invalid identifier" ), 400
0 commit comments