使用python多处理时,使用mysql获得不同的结果

时间:2012-02-19 20:16:51

标签: python mysql multiprocessing

我无法弄清楚我做错了什么(或者如何纠正它)。显示一些代码可能更容易(它与我正在做的有点简化,但它证明了我的观点):

from multiprocessing import Pool
import MySQLdb
import sys

#sql connection
try:
    conn = MySQLdb.connect (host = "127.0.0.1",user = "user",passwd = "password", db = "mydb")
except MySQLdb.Error, e:
     print "Error %d: %s" % (e.args[0], e.args[1])
     sys.exit (1)

#with database
cursor = conn.cursor ()
cursor.execute ("DROP TABLE IF EXISTS data_table")
cursor.execute ("""
    CREATE TABLE data_table(
        value     CHAR(80)
    ) ENGINE=MyISAM 
""")

cursor.execute (""" INSERT INTO data_table (value) VALUES ('%s')""" % [0, 0]) #need to insert basecase
conn.commit()


def build_table(i,x):    # i is index, x is data[i]
    conn = MySQLdb.connect (host = "127.0.0.1",user = "user",passwd = "password", db = "mydb")
    cursor = conn.cursor ()
    #print i,x
    target_sum = 100
    for s in range(target_sum + 1): 
        for c in range(target_sum + 1): 
            #print c, i
            cursor.execute ("""
INSERT INTO data_table (value) 
   SELECT  '%s'
   FROM dual
   WHERE ( SELECT COUNT(*) FROM data_table WHERE value='%s' )
         = 1
     AND NOT EXISTS
         ( SELECT * FROM data_table WHERE value='%s' )
           """ % ([s, i+1], [s - c * x, i], [s, i+1]))
            conn.commit()

    conn.close()

data = [2,5,8]
pool = Pool(processes=4)
for i, x in enumerate(data): 
    build_table(i,x) #creates 250 records
    #pool.apply_async(build_table, (i, x))
pool.close()
pool.join()

print 'completed'

它基本上在mysql中创建了一个表。上面的代码创建了250个条目(这是正确的),但如果您在for循环中注释掉build_table(i,x)并取消注释pool.apply_async(build_table, (i, x)),则它只创建52条记录。为什么在对同一个函数进行多处理时会有什么不同,有什么我可以做的来修复它所以结果是一样的(我认为快速提交更新会修复它但没有运气)?

如果我玩pool = Pool(processes=4)并将其更改为1,它可以工作,但我猜这是预期的,因为它不是那时的多处理。另外,如果它有助于我使用InnoDB。

更新:当我更改为MyISAM时,我会更新240个结果(不是我需要的250个,但比52个好得多)。

UPDATE2:mysql命令合并为一个命令,结果似乎有所不同。有时我在数据库中得到248个结果,有时240或更少。也许多处理会导致预期和实际结果之间存在分歧?

1 个答案:

答案 0 :(得分:2)

我会尝试将2个Selects和Insert组合在一个Insert语句中:

#print c, i
cursor.execute(""" SELECT value FROM data_table WHERE value='%s' """ % ([s - c * x, i]))
if cursor.rowcount == 1:
    cursor.execute(""" SELECT value FROM data_table WHERE value='%s' """ % [s, i+1])
    if cursor.rowcount == 0:
        cursor.execute (""" INSERT INTO data_table (value) VALUES ('%s')""" % [s, i+1])

类似于:

#print c, i
cursor.execute ("""
    INSERT INTO data_table (value) 
       SELECT  '%s'
       FROM dual
       WHERE ( SELECT COUNT(*) FROM data_table WHERE value='%s' )
             = 1
         AND NOT EXISTS
             ( SELECT * FROM data_table WHERE value='%s' )
               """ % ([s, i+1], [s - c * x, i], [s, i+1]))

不确定最后一行的语法。你需要传递3个参数。