Python:在执行之前根据列表长度附加到mysql命令?

时间:2014-03-06 06:38:40

标签: python mysql

我想在执行之前将条件子句附加到mysql命令,这将根据我想从数据库中提取的元素数量而有所不同。

例如,我有大量基因列表,对于每个感兴趣的基因,我都有所有外显子的坐标。

Gene_ID外显子开始结束

geneA exon1 325 359

geneA exon2 554 601

geneB exon1 870 900

geneB exon2 990 1010

geneB exon3 1200 1350

如您所见,geneA有2个外显子,geneB有3个外显子。我想执行如下命令来返回外显子坐标内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))

如果它只是一个或两个外显子就可以了,但是我如何处理可能很长的外显子列表呢?如何在执行之前动态重新格式化命令?

真的很感激一些帮助,因为我很难过!

1 个答案:

答案 0 :(得分:0)

您可以动态构建一个存储外显子数据的字典,并根据这样的字典构建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)