我遇到了Python的subprocess.Popen方法的问题。
这是一个测试脚本,演示了问题。它正在Linux系统上运行。
#!/usr/bin/env python
import subprocess
import time
def run(cmd):
p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
return p
### START MAIN
# copy some rows from a source table to a destination table
# note that the destination table is empty when this script is run
cmd = 'mysql -u ve --skip-column-names --batch --execute="insert into destination (select * from source limit 100000)" test'
run(cmd)
# check to see how many rows exist in the destination table
cmd = 'mysql -u ve --skip-column-names --batch --execute="select count(*) from destination" test'
process = run(cmd)
count = (int(process.communicate()[0][:-1]))
# if subprocess.Popen() waited for the child to terminate than count should be
# greater than 0
if count > 0:
print "success: " + str(count)
else:
print "failure: " + str(count)
time.sleep(5)
# find out how many rows exists in the destination table after sleeping
process = run(cmd)
count = (int(process.communicate()[0][:-1]))
print "after sleeping the count is " + str(count)
通常这个脚本的输出是:
success: 100000
但有时候这会变得
failure: 0
after sleeping the count is 100000
请注意,在失败的情况下,插入操作后立即执行的选择查询显示零行,但在休眠5秒钟后,第二个选择正确地显示了100,000行的计数。我的结论是以下之一为真:
- subprocess.Popen没有等待子线程终止-这似乎与文档相矛盾
- mysql插入不是原子性的-我对mysql的理解表明插入是原子性的
- 选择查询没有立即看到正确的行数-根据一个比我更了解mysql的朋友,这也不应该发生
顺便提一句,我知道这是一种从Python与MySQL交互的hacky方法,而MySQLdb可能不会有这个问题,但我很好奇为什么这种方法不起作用。