python操作mysql数据库(百库百表)
问题描述:
今天下午跑某项目db需求,百库百表清脏数据,然后自己写了个python脚本,跑完之后通知项目,然后项目给玩家发奖励了,结果悲催了,所有的mysql操作没有执行成功(没有报错,因而以为执行成功)。
以下是我的python脚本,传两个文件作为参数,host.txt 以及 update.sql
#-*-coding:UTF-8-*-
importsys
importMySQLdb
importdatetime
dbuser='xxx'
dbpwd='xxx'
DB_NUM=100
TB_NUM=100
args=sys.argv
iflen(args)!=3:
print"USAGE: %s host.txt update.sql"%args[0]
sys.exit()
start=datetime.datetime.now()
print"Start Time : %s "%start.strftime('%Y-%m-%d %H:%M:%S')
hostfile=args[1]
sqlfile=args[2]
rhost=open(hostfile)
hostlist=rhost.readlines()
rhost.close()
rsqls=open(sqlfile)
sqllist=rsqls.readlines()
rsqls.close()
forhostinhostlist:
host=host.strip()
ip=host.split(' ')[0]
pt=host.split(' ')[1]
conn=MySQLdb.connect(ip,dbuser,dbpwd,port=int(pt))
cursor=conn.cursor()
cursor.execute('SET NAMES UTF8')
sqls=[]
foriinrange(DB_NUM):
sqls.append("%s"%str(i).zfill(2))
forsqlinsqls:
db=sql
#print'ip=%s ; port=%s ; db=%s'%(ip,pt,db)
forjinrange(TB_NUM):
ifTB_NUM>10:
j=str(j).zfill(2)
forsqlinsqllist:
ct=sql.strip()%(db,str(j)) cursor.execute(ct)
printct
conn.close()
end=datetime.datetime.now()
print"End Time : %s "%end.strftime('%Y-%m-%d %H:%M:%S')
update.sql如下:
解决:
临时写了个shell脚本,跑完需求,成功执行。
其中传入的$1为包含10000条操作的delete语句文件
发现问题:
开始以为自己远端没有执行,然后重新在test库上使用以上python脚本create百表,登上去查看,发现操作成功。
但是insert、update、以及delete操作无效。
查资料得知,mysql的ddl操作是隐式提交的,而dml是需要显示commit才能提交 成功,而我的这个python脚本没有调用cursor.commit(),故而close之后并没有提交相应的操作。
这里要区分shell中连接执行和python MySQLdb模块中连接执行的区别:
①shell中写的是连接到库上默认autocommit是开启的,故而执行时自动提交的,
②而pyrhon的该模块在dml操作之后调用conn.commit()显示提交或者在连接mysql之后执行设置conn.autocommit(1)。这是由于MySQLdb模块在连接mysql之后关闭了自动提交。需要注意的是这里针对的是innodb存储引擎,因为mysaim不支持事务
今天下午跑某项目db需求,百库百表清脏数据,然后自己写了个python脚本,跑完之后通知项目,然后项目给玩家发奖励了,结果悲催了,所有的mysql操作没有执行成功(没有报错,因而以为执行成功)。
以下是我的python脚本,传两个文件作为参数,host.txt 以及 update.sql
点击(此处)折叠或打开
#!/usr/bin/env python#-*-coding:UTF-8-*-
importsys
importMySQLdb
importdatetime
dbuser='xxx'
dbpwd='xxx'
DB_NUM=100
TB_NUM=100
args=sys.argv
iflen(args)!=3:
print"USAGE: %s host.txt update.sql"%args[0]
sys.exit()
start=datetime.datetime.now()
print"Start Time : %s "%start.strftime('%Y-%m-%d %H:%M:%S')
hostfile=args[1]
sqlfile=args[2]
rhost=open(hostfile)
hostlist=rhost.readlines()
rhost.close()
rsqls=open(sqlfile)
sqllist=rsqls.readlines()
rsqls.close()
forhostinhostlist:
host=host.strip()
ip=host.split(' ')[0]
pt=host.split(' ')[1]
conn=MySQLdb.connect(ip,dbuser,dbpwd,port=int(pt))
cursor=conn.cursor()
cursor.execute('SET NAMES UTF8')
sqls=[]
foriinrange(DB_NUM):
sqls.append("%s"%str(i).zfill(2))
forsqlinsqls:
db=sql
#print'ip=%s ; port=%s ; db=%s'%(ip,pt,db)
forjinrange(TB_NUM):
ifTB_NUM>10:
j=str(j).zfill(2)
forsqlinsqllist:
ct=sql.strip()%(db,str(j)) cursor.execute(ct)
printct
conn.close()
end=datetime.datetime.now()
print"End Time : %s "%end.strftime('%Y-%m-%d %H:%M:%S')
update.sql如下:
点击(此处)折叠或打开
deletefromXSY_%s.t_xsy_equip_cloth_%swhere(clothid>=201675andclothid<=201700)or(clothid>=201725andclothid<=201751); host.txt如下:点击(此处)折叠或打开
192.168.xx.xx 3306每执行一条语句都print出来,结果是成功打印出了10000条,但是上库看binlog日志并没有任何记录,数据也没有变化解决:
临时写了个shell脚本,跑完需求,成功执行。
其中传入的$1为包含10000条操作的delete语句文件
点击(此处)折叠或打开
#!/bin/bashuser=xxxpwd=xxxwhile read sqldoecho $sql/usr/bin/mysql -h"192.168.xxx.xx" -P3306 -utab -ptab -e "${sql}"done < $1发现问题:
开始以为自己远端没有执行,然后重新在test库上使用以上python脚本create百表,登上去查看,发现操作成功。
但是insert、update、以及delete操作无效。
查资料得知,mysql的ddl操作是隐式提交的,而dml是需要显示commit才能提交 成功,而我的这个python脚本没有调用cursor.commit(),故而close之后并没有提交相应的操作。
这里要区分shell中连接执行和python MySQLdb模块中连接执行的区别:
①shell中写的是连接到库上默认autocommit是开启的,故而执行时自动提交的,
②而pyrhon的该模块在dml操作之后调用conn.commit()显示提交或者在连接mysql之后执行设置conn.autocommit(1)。这是由于MySQLdb模块在连接mysql之后关闭了自动提交。需要注意的是这里针对的是innodb存储引擎,因为mysaim不支持事务
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。