77from typing import Any , Dict , List , Optional
88
99from flask import has_app_context
10- from sqlalchemy import text
10+ from sqlalchemy import Column , MetaData , Table , func , select
1111from sqlalchemy .exc import SQLAlchemyError
1212from sqlalchemy .engine import Engine
1313from sqlalchemy .orm import Session
5050MANUAL_DATABASE_SCHEMAS = {
5151 name : {
5252 ** DEFAULT_SAMPLE_SCHEMA ,
53- "identifier_type" : "agi " ,
53+ "identifier_type" : "gene_model " ,
5454 "metadata" : {},
5555 }
5656 for name in _MANUAL_DEFAULT_DATABASES
@@ -64,7 +64,7 @@ def _build_schema_catalog() -> Dict[str, Dict[str, Any]]:
6464 schema = dict (DEFAULT_SAMPLE_SCHEMA )
6565 schema .update (
6666 {
67- "identifier_type" : spec .get ("identifier_type" , "agi " ),
67+ "identifier_type" : spec .get ("identifier_type" , "gene_model " ),
6868 "metadata" : spec .get ("metadata" ) or {},
6969 }
7070 )
@@ -157,45 +157,28 @@ def query_efp_database_dynamic(
157157 query_id = upper_id if species else gene_id
158158 gene_case_insensitive = bool (species )
159159
160- gene_col = schema ["gene_column" ]
161- sample_col = schema ["sample_column" ]
162- value_col = schema ["value_column" ]
163- table_name = schema ["table" ]
164-
165- # Column/table names come from the internal schema catalog, but validate anyway before interpolating into SQL
166- for identifier , name in [
167- (gene_col , "gene_column" ),
168- (sample_col , "sample_column" ),
169- (value_col , "value_column" ),
170- (table_name , "table" ),
171- ]:
172- if not re .match (r"^[a-zA-Z_][a-zA-Z0-9_]*$" , identifier ):
173- return {
174- "success" : False ,
175- "error" : f"Invalid schema identifier for { name } : { identifier } " ,
176- "error_code" : 500 ,
177- }
160+ table = Table (
161+ schema ["table" ],
162+ MetaData (),
163+ Column (schema ["gene_column" ]),
164+ Column (schema ["sample_column" ]),
165+ Column (schema ["value_column" ]),
166+ )
167+ gene_col = table .c [schema ["gene_column" ]]
168+ sample_col = table .c [schema ["sample_column" ]]
169+ value_col = table .c [schema ["value_column" ]]
178170
179- gene_column_expr = f"UPPER( { gene_col } )" if gene_case_insensitive else gene_col
180- params = { "gene_id" : query_id .upper () if gene_case_insensitive else query_id }
181- where_clauses = [ f" { gene_column_expr } = :gene_id" ]
171+ gene_expr = func . upper ( gene_col ) if gene_case_insensitive else gene_col
172+ gene_value = query_id .upper () if gene_case_insensitive else query_id
173+ stmt = select ( sample_col . label ( "sample" ), value_col . label ( "value" )). where ( gene_expr == gene_value )
182174
183175 if sample_ids :
184176 filtered = [s for s in sample_ids if s ]
185177 if filtered :
186- sample_column_expr = f"UPPER({ sample_col } )" if sample_case_insensitive else sample_col
187- sample_conditions = []
188- for idx , sample in enumerate (filtered ):
189- key = f"sample_{ idx } "
190- params [key ] = sample .upper () if sample_case_insensitive else sample
191- sample_conditions .append (f"{ sample_column_expr } = :{ key } " )
192- where_clauses .append (f"({ ' OR ' .join (sample_conditions )} )" )
193-
194- query_sql = text (
195- f"SELECT { sample_col } AS sample, { value_col } AS value "
196- f"FROM { table_name } "
197- f"WHERE { ' AND ' .join (where_clauses )} "
198- )
178+ if sample_case_insensitive :
179+ stmt = stmt .where (func .upper (sample_col ).in_ ([s .upper () for s in filtered ]))
180+ else :
181+ stmt = stmt .where (sample_col .in_ (filtered ))
199182
200183 engine = _get_engine (database )
201184 results = None
@@ -204,7 +187,7 @@ def query_efp_database_dynamic(
204187 if engine :
205188 try :
206189 with Session (engine ) as session :
207- results = session .execute (query_sql , params ).all ()
190+ results = session .execute (stmt ).all ()
208191 except SQLAlchemyError as exc :
209192 last_error = f"query failed: { exc } "
210193 print (f"[warn] { last_error } " )
0 commit comments