pythondump⽂件_如何⽤python解析mysqldump⽂件
⼀、前⾔
最近在做离线数据导⼊HBase项⽬,涉及将存储在Mysql中的历史数据通过bulkload的⽅式导⼊HBase。由于源数据已经不在DB中,⽽是以⽂件形式存储在机器磁盘,此⽂件是mysqldump导出的格式。如何将mysqldump格式的⽂件转换成实际的数据⽂件提供给bulkload作转换,是需要考虑的⼀个问题。
⼆、思路
我们知道mysqldump导出的⽂件主要是Insert,数据库表结构定义语句。⽽要解析的对象也主要是包含INSERT关键字记录,这样我们就把问题转换成如何从dmp⽂件解析Insert语句。接触过dmp⽂件的同学应该了解,其INSERT语句的结构,主要包含表名、字段名、字段值,
这⾥⾯主要包含⼏个关键字:INSERT INTO, VALUES。我们要做的就是把Values括号后的字段值给解析出来,这个过程需要考虑VALUES后⾯包含的是多少⾏的记录,有可能导出的记录Values后⾯包含多⾏对应mysql中存储的记录。
在解析⽂件过程中,我⾃然想到⽤Python来写,因为Python在处理⽂件⽅⾯有很多优势,也⽐较简单。在处理DMP⽂件这块,考虑到字段值间是⽤逗号分割的,在python中正好⼀个模块可以很好的来处理此
类格式 ,即⼤家很熟悉的CSV模块,在处理CSV类型的⽂件有很多优势。在这⾥我们把CSV模块有在解析dmp⽂件,同时加⼀些解析逻辑,可以很好解决此类问题。
同时,我们要处理的dmp⽂件是经过压缩的,并且单个⽂件都⽐较⼤,都是Gigbytes的,在读取时需要注意机器内存⼤⼩,不能⼀次读出所有的数据,python也考虑到此类问题,采⽤的⽅法是惰性取值,即在真正使⽤时才从磁盘中加载相应的⽂件数据。如果想加块解析,还可以采集多进程或多线程的⽅法。
三、⽅法
处理流程图如下所⽰:
代码如下图所⽰:
1 #!/usr/bin/env python
2 importfileinput
3 importcsv
4 importsys
5 importgzip6
7
8 #设定CSV读取的最⼤容量
9 csv.field_size_limit(sys.maxsize)10
11 defcheck_insert(line):12 """
13 返回语句是否以insert into开头,如果是返回true,否则返回false14 """
15 return line.startswith('INSERT INTO') orFalse16
17
18 defget_line_values(line):19 """
20 返回Insert语句中包含Values的部分21 """
22 return line.partition('VALUES')[2]23
24
25 defcheck_values_style(values):26 """
27 保证INSERT语句满⾜基本的条件,即包含(右括号28 """
29
30 if values and values[0] == '(':31 returnTrue32 returnFalse33
34 defparse_line(values):35 """
36 创建csv对象,读取INSERT VALUES 字段值37 """
38 latest_row =[]39
40 reader = ader([values], delimiter=',',41 doublequote=False,42 escapechar='\\',43 quotechar="'",44 strict=True45 )46
47
48 for reader_row inreader:49 for column inreader_row:50 #判断字段值是否为空或为NULL
51 if len(column) == 0 or column == 'NULL':52 latest_row.append("")53 continue
54
55 #判断字段开头是否以(开头,如果是则说明此VALUES后⾯不只包含⼀⾏数据,可能有多⾏,要分别解析
56 if column[0] == "(":57 new_row =False58 if len(latest_row) >0:59 #判断⾏是否包含),如果包含则说明⼀⾏数据完毕
60 if latest_row[-1][-1] == ")":61 #移除)
62 latest_row[-1] = latest_row[-1][:-1]63 if latest_row[-1] == "NULL":64 latest_row[-1] = ""
65 new_row =True66 #如果是新⾏,则打印该⾏
67 ifnew_row:68 line="}}}{{{".join(latest_row)69 print "%s" %line70 latest_row =[]71
72 if len(latest_row) ==0:73 column = column[1:]74
75 latest_row.append(column)76 #判断⾏结束符
77 if latest_row[-1][-2:] == ");":78 latest_row[-1] = latest_row[-1][:-2]79 if latest_row[-1] == "NULL":80 latest_row[-1] = ""
81
82 line="}}}{{{".join(latest_row)83 print "%s" %line84
85 defmain():86
87 filename=sys.argv[1]88 try:89 #惰性取⾏
90 with gzip.open(filename,"rb") as f:91 for line inf:92 ifcheck_insert(line):93 values =get_line_values(line)94
ifcheck_values_style(values):95 parse_line(values)96 exceptKeyboardInterrupt:it(0)98
99 if __name__ == "__main__":100 main()
View Code
四、总结
python怎么读文件夹下的文件夹
总的说来,主要是利⽤Python的CSV模块来解析DMP⽂件的INSERT语句,如果DMP⽂件不规整,可能还是有些问题。对于dmp⽂件很⼤情况,也是需要考虑解析时间效率问题,可以考虑增加多进程或多线程机制。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。