r onedir in dirs:
dbname=onedir.translate(map1).translate(map2)
conn.select_db(dbname)
print "DB:"+dbname+" ."
files=os.listdir(root+"/"+onedir)
os.chdir(root+"/"+onedir)
for onefile in files:
# it seems that all is AVERAGE
tablename=onefile[:-4].translate(map1)
data=rrdtool.fetch(onefile,"AVERAGE")
firsttime=data[0][0] www.2cto.com
count=0
while count < 5761:
time=firsttime+15*count
value=data[2][count][0]
if value==None:
count+=1
continue
if dbname=="__SummaryInfo__":
num=data[2][count][1]
fvalue=[time,str(value),str(num)]
try:
cursor.execute("insert into "+tablename+" values(%s,%s,%s)",fvalue)
except MySQLdb.IntegrityError:
pass
else: www.2cto.com
fvalue=[time,str(value)]
try:
cursor.execute("insert into "+tablename+" values(%s,%s)",fvalue)
# print "OK"+str(count)
except MySQLdb.IntegrityError:
pass www.2cto.com
count+=1
conn.commit()
print "UPDATING TABLE "+tablename
cursor.close();
说明:
1.python有RRDTOOL的模块,相应的命令都已经可以通过模块内的函数直接调用,并且结果是
Python的列表或者元组
,很容易遍历。另外有一种方法就是通过调用外部命令将rrd
数据库导出到XML中(RRDTOOL内置有此功能),好处是XML
里面的数据极其相近,缺点是太繁琐,效率也不高,还要解析XML。
2.count是RRD里存储的数据的行数,这里为了省事直接设置成了默认的值。严谨的话应该是先通过RRDTOOL INFO取得
想关的结构信息,得到这个值,然后再调用。rrdtool.fetch即可取得所存储的所有值。
3.关于commit。刚开时对API不熟悉,没有加这一句,结果数据都没导进去。第一次加在每次insert 之后,结果插入 www.2cto.com
速度奇慢,更新一次要差不多一天,根本没有用。放到后面之后就很快了。
4.因为插入的频率和RRD更新的频率不一样,为了保证数据的连续性(不丢失),插入的频率要比更新的频率高。这样会有
很多重复的数据,这里用主键(时间戳,为UNIX秒数)和IntegrityError来跳过那些已经插入的数据。当初这样做的时候
已经考虑到一个问题,就是当表里原有行数很多时,到后面插入的速度有多慢?(单个表每天更新的数据为5700行左右,一个
月为17万行左右,一年就会超过200万行)。现在我运行的结果是表中已有5万行数据,插入速度并没有明显的减慢,想接着再
运行一段时间观察一下。如果太慢就得换一个方法。
作者 西城