Python脚本中的MySQL InterfaceError

时间:2015-04-11 12:45:15

标签: python mysql

我有以下定义:

def sql_processes(db1, infile_name, z):
    cursor = db1.cursor()
    print "Processing " + infile_name
    PrintLog("Adding " + infile_name + "to MySQL...")
    vcf_reader = vcf.Reader(open(infile_name, 'r'))
    for record in vcf_reader:
        snp_position='_'.join([record.CHROM, str(record.POS)])
        ref_F = float(record.INFO['DP4'][0])
        ref_R = float(record.INFO['DP4'][1])
        alt_F = float(record.INFO['DP4'][2])
        alt_R = float(record.INFO['DP4'][3])
        AF = (alt_F+alt_R)/(alt_F+alt_R+ref_F+ref_R)
        sql_test_query = "SELECT * from snps where snp_pos='" + snp_position + "'"
        try:
            sql_insert_table = "INSERT INTO snps (snp_pos, " + str(z) + "g) VALUES ('" + snp_position + "', " + str(AF) + ")"
            cursor.execute(sql_insert_table)
        except db1.IntegrityError, e:
            sql_insert_table = "UPDATE snps SET " + str(z) + "g=" + str(AF) + " WHERE snp_pos='" + snp_position + "'";
            cursor.execute(sql_insert_table)
        db1.commit()
    cursor.close()
    print "Processing of " + infile_name + "done!"
    PrintLog("Added " + infile_name + "to MySQL!")

def extractAF(files_vcf):
    z=6
    snp_dict=[]
    db1 = MS.connect(host="localhost",user="root",passwd="sequentia2",db="SUPER_SNP_calling")
    threads = []
    for infile_name in sorted(files_vcf):
        t = Thread(target = sql_processes, args = (db1, infile_name, z))
        threads.append(t)
        z+=1
    count_t = 1
    my_threads = []
    for t in threads:
        t.start()
        my_threads.append(t)
        if count_t == 8:
            for x in my_threads:
                x.join()
            my_threads = []
            count_t = 0
        count_t+=1

此处的目的是同时读取多个文件并更新MySQL数据库。但是,这会引发以下错误:

Exception in thread Thread-1:
Traceback (most recent call last):
  File "/usr/lib/python2.7/threading.py", line 810, in __bootstrap_inner
    self.run()
  File "/usr/lib/python2.7/threading.py", line 763, in run
    self.__target(*self.__args, **self.__kwargs)
  File "./SUPER_mysql4.py", line 457, in sql_processes
    cursor.execute(sql_insert_table)
  File "/usr/local/lib/python2.7/dist-packages/MySQLdb/cursors.py", line 202, in execute
    self.errorhandler(self, exc, value)
  File "/usr/local/lib/python2.7/dist-packages/MySQLdb/connections.py", line 36, in defaulterrorhandler
    raise errorclass, errorvalue
InterfaceError: (0, '')

*** Error in `Segmentation fault (core dumped)

为什么会这样?

2 个答案:

答案 0 :(得分:0)

我认为此错误基于mysql锁定

  

MySQL对MyISAM,MEMORY和MERGE表使用表级锁定,为BDB表使用页级锁定,对InnoDB表使用行级锁定。表更新的优先级高于表检索。因此,当释放锁定时,锁定对写入锁定队列中的请求可用,然后对读取锁定队列中的请求可用。这可确保即使表中存在大量SELECT活动,对表的更新也不会“缺乏”。但是,如果表有很多更新,SELECT语句将一直等到没有更新。

由于使用不同的线程插入同一个表可能会锁定表以插入1st线程开始。所以其他线程和SELECT必须等待所有{{1}中的完成INSERT }}

这可以帮助你

threads

for t in threads: t.start() t.join()

  

等到线程终止。这会阻塞调用线程,直到调用join()方法的线程终止 - 正常或通过未处理的异常 - 或直到发生可选的超时

了解更多http://dev.mysql.com/doc/refman/5.0/en/internal-locking.html

答案 1 :(得分:0)

MySQLdb不支持多个线程写入同一连接。您必须为每个线程启动一个新连接,或者以其他方式确保每个连接仅由一个线程同时使用。
请参阅this答案,了解描述问题的MySQLdb user guide摘录。或直接影响您的部分:

  

MySQL协议无法一次使用同一连接处理多个线程。 (...)这样做的一般结果是:不要在线程之间共享连接。 (...)如果让两个线程同时使用连接,MySQL客户端库可能会升级并死掉。