我希望在执行之前将条件子句附加到mysql命令中,这些子句将根据我想从DB中提取的元素数量而有所不同。
例如,我有大量的基因列表,对于每一个感兴趣的基因,我都有所有外显子的坐标。
Gene_ID外显子起始端
geneA exon1 325 359
geneA exon2 554601
geneB exon1 870 900
geneB exon2 990 1010
geneB exon3 1200 1350
如您所见,geneA有两个外显子,geneB有三个外显子。我希望执行如下命令,以返回外显子坐标内DB中所有元素的计数。
select count(*) from db_x where position between exon1_start and exon1_end and position between exon2_start and exon2_end;由于每个基因的外显子数目不同(有些基因可能包含数十个外显子),在执行总体命令之前,我需要为每个外显子附加一个附加的“和位置在exon_end和exon_start之间”的条件语句。
我正努力想出一个合乎逻辑的解决方案。目前,对于每个基因,我将向函数传递一个连接start_end位置的列表,然后该函数将查询mysql服务器。例如geneA‘325.359’,‘554.601’
我使用的命令(在设置光标之后)如下所示;
cur.execute('select count(*) from db_x where position between '+str(exon1_start)+' and '+str(exon1_end)+' and position between +'str(exon2_start)+' and '+str(exon2_end))如果只是一个或两个外显子,这就好了,但是我如何处理可能非常长的外显子列表呢?在执行命令之前,我如何动态地重新格式化命令?
真的很感谢你的帮助,因为我很困惑!
发布于 2014-03-06 07:27:08
您可以动态地构建一个存储外显子数据的字典,并基于这样的字典构建sql查询:
gene_exons_dict = dict()
def add_exon_to_gene(gene_name,gene_exon):
if gene_name not in gene_exons_dict:
gene_exons_dict[gene_name] = []
tmp_exons_dict = {'start': gene_exon[0], 'end': gene_exon[1]}
gene_exons_dict[gene_name].append(tmp_exons_dict)
def get_sql_query_for_gene(gene_name):
if gene_name not in gene_exons_dict:
raise Exception("exons not defined for gene: %s" % gene_name)
sql_query = 'select count(*) from db_x.tb_y WHERE '
exons_count = len(gene_exons_dict[gene_name])
for exon_data in gene_exons_dict[gene_name]:
sql_query += '(position >'+str(exon_data['start'])+' AND position <'+str(exon_data['end'])+')'
if exons_count > 1:
sql_query += ' AND ' # change it to OR if query should return sum of sets instead of their intersection
# removing last and for multi-exons case
if exons_count > 1:
sql_query=sql_query[:-5]
return sql_query
if __name__ == '__main__':
add_exon_to_gene('gene1', [1, 2])
add_exon_to_gene('gene1', [3, 8])
add_exon_to_gene('gene1', [10, 15])
add_exon_to_gene('gene2', [20, 25])
print get_sql_query_for_gene('gene1')
print get_sql_query_for_gene('gene2')它提供了输出:
C:\tmp>python dynamicDictTest.py
select count(*) from db_x.tb_y WHERE (position >1 AND position <2) AND (position >3 AND position <8) AND (position >10 AND position <15)
select count(*) from db_x.tb_y WHERE (position >20 AND position <25)
https://stackoverflow.com/questions/22216976
复制相似问题