当变量 NUMBER_OF_ITERATIONS 设置为1时,一切正常......但是当我将其更改为大于1的任何值时,我会遇到一些问题。
首先,在这种情况下,当我打印 res 的值时,我得到一个巨大的数字(如18446744073709551615)。
其次,但最重要的是,在这种情况下,脚本无法处理数据,因为值的长度始终为0 ...
if __name__ == '__main__':
NUMBER_OF_ITERATIONS = 2
conn = DBconnection() # return a database connection
for i in range( NUMBER_OF_ITERATIONS ):
cursor = conn.cursor()
res = cursor.execute( 'SELECT field
FROM table
WHERE other_field = 0
LIMIT 10 LOCK IN SHARE MODE' )
print '# of selected rows: ' + str(res)
values = []
for elem in cursor.fetchall():
if elem != None:
values.append( list(elem).pop() )
if len( values ) != 0:
# do something...
else:
print 'NO VALUES AVAILABLE'
cursor.close()
break
conn.close()
print 'DONE'
我正在使用InnoDB存储引擎,同时在此脚本中还有另一个脚本python,它在同一个表上上传数据(使用构造LOAD DATA INFILE)。
我认为这可能是由于加载数据引起的表锁定,但是从一到二(或更多)迭代有什么不同?一次迭代一切都很好,而即使第一次迭代也变坏了。我不明白这一点。
答案 0 :(得分:2)
我无法使用以下代码重现该问题。你可以修改它来证明错误吗?
import config
import MySQLdb
import multiprocessing as mp
import random
import string
import time
def random_string(n):
return ''.join(random.choice(string.letters) for _ in range(n))
def generate_data():
conn=MySQLdb.connect(
host=config.HOST,user=config.USER,
passwd=config.PASS,db='test')
cursor=conn.cursor()
while True:
with open('/tmp/test.dat','w') as f:
for _ in range(20):
f.write('{b}\n'.format(b=random_string(10)))
# sql='LOCK TABLES foo WRITE'
# cursor.execute(sql)
sql="LOAD DATA INFILE '/tmp/test.dat' INTO TABLE test.foo"
cursor.execute(sql)
conn.commit()
# sql='UNLOCK TABLES'
# cursor.execute(sql)
time.sleep(0.05)
def setup_innodb(connection):
cursor=connection.cursor()
sql='DROP TABLE IF EXISTS foo'
cursor.execute(sql)
sql='''\
CREATE TABLE `foo` (
`bar` varchar(10) NOT NULL
) ENGINE=InnoDB
'''
cursor.execute(sql)
connection.commit()
if __name__ == '__main__':
NUMBER_OF_ITERATIONS = 20
conn=MySQLdb.connect(
host=config.HOST,user=config.USER,
passwd=config.PASS,db='test')
setup_innodb(conn)
# Start a process which is "simultaneously" calling LOAD DATA INFILE
proc=mp.Process(target=generate_data)
proc.daemon=True
proc.start()
for i in range( NUMBER_OF_ITERATIONS ):
cursor = conn.cursor()
# sql='''SELECT field
# FROM table
# WHERE other_field = 0
# LIMIT 10 LOCK IN SHARE MODE'''
# sql='LOCK TABLES foo READ'
# cursor.execute(sql)
sql='''SELECT *
FROM foo
LOCK IN SHARE MODE
'''
res = cursor.execute(sql)
print '# of selected rows: ' + str(res)
values = cursor.fetchall()
# http://dev.mysql.com/doc/refman/5.0/en/innodb-locking-reads.html
# Locks set by LOCK IN SHARE MODE and FOR UPDATE reads are released when
# the transaction is committed or rolled back.
conn.commit()
time.sleep(0.1)
conn.close()
print 'DONE'
产量
# of selected rows: 0
# of selected rows: 40
# of selected rows: 80
# of selected rows: 120
# of selected rows: 160
# of selected rows: 180
# of selected rows: 220
# of selected rows: 260
# of selected rows: 300
# of selected rows: 340
# of selected rows: 360
# of selected rows: 400
# of selected rows: 440
# of selected rows: 460
# of selected rows: 500
# of selected rows: 540
# of selected rows: 580
# of selected rows: 600
# of selected rows: 640
# of selected rows: 680
DONE