Python使用gevent实现MySQL数据转XML的多任务处理
本文介绍利用Python的gevent库实现MySQL数据库表数据转换为XML格式的方法。针对文件I/O阻塞问题,通过多任务并发处理提升效率。文中对比了两种list_to_xml函数的实现,后者通过直接写入文件流和特殊字符转义,使处理速度提升上百倍,适用于需要与Navicat导出格式保持一致的场景。
本文分享一个使用Python实现MySQL数据转换为XML格式的多任务处理示例,供读者参考学习。
该方案旨在使导出的XML文件格式尽可能与Navicat工具导出的结果保持一致。
程序采用gevent库进行并发控制,由于文件I/O操作存在阻塞特性,因此该实现并非完全异步。
核心代码文件名为mysql2xml.py,具体实现如下:
# -*- coding: utf-8 -*-
'''
Created on 2014/12/27
@author: Yoki
'''
import gevent
import pymysql
from pymysql.cursors import DictCursor
import re
import codecs
db_conn = None
def init_mysql_connect(*args, **kwargs):
global db_conn
db_conn = pymysql.connect(*args, **kwargs)
def list_to_xml(result_cur, key_list):
'''
mysql 结果集转xml,非xml标准导出方式; xml dom 不支持相同名字的node
:param result_cur:
:param key_list:
:return:
'''
content = ''
content += '<?xml version="1.0" encoding="UTF-8" ?>\r\n'
content += '<RECORDS>\r\n' # root节点
for item in result_cur:
content += '\t<RECORD>\r\n'
for k in key_list:
v = item.get(k, '')
real_value = v
content += '\t\t<%s>%s</%s>\r\n' % (k, real_value, k)
content += '\t</RECORD>\r\n'
content += '</RECORDS>\r\n'
return content
def get_table_rows(tb_name):
'''
获取mysql表rows
:param tb_name:
:return:
'''
global db_conn
rows = []
cursor = db_conn.cursor(cursor=DictCursor)
cursor.execute('select * from %s' % tb_name)
for row in cursor:
rows.append(row)
return rows
def get_table_keys(tb_name):
'''
获取表中字段,顺序 为创建表时的顺序
:param tb_name:
:return:
'''
global db_conn
cursor = db_conn.cursor(cursor=DictCursor)
cur = cursor.execute('show create table %s' % tb_name)
if cur != 1:
raise Exception
for r in cursor:
create_sql = r['Create Table']
fields = re.findall('`(.*?)`', create_sql)
result = []
# 处理字段
for i in xrange(1, len(fields)):
field = fields[i]
if field in result:
continue
result.append(field)
return result
return []
def mysql_to_xml(tb_name, output_dir='xml', postfix='xml'):
'''
mysql数据导出xml,
:param tb_name: 数据库表名
:param output_dir:
:param postfix:
:return:
'''
rows = get_table_rows(tb_name)
keys = get_table_keys(tb_name)
content = list_to_xml(rows, keys)
fp = codecs.open('%s/%s.%s' % (output_dir, tb_name, postfix), 'w', 'utf-8')
fp.write(content)
fp.close()
tb_list = [
'tb_item',
'tb_state'
]
if __name__ == '__main__':
init_mysql_connect(host="localhost", user='user', password="password", database='test', port=3306,
charset='utf8')
jobs = []
for tb_name in tb_list:
jobs.append(gevent.spawn(mysql_to_xml, tb_name))
gevent.joinall(jobs)
通过优化list_to_xml函数,处理速度实现了百倍以上的提升。
def list_to_xml(result_cur, key_list):
fp = codecs.open('test.xml'), 'w', 'utf-8')
fp.write('<?xml version="1.0" encoding="UTF-8" ?>\r\n')
fp.write('<RECORDS>\r\n')
for item in result_cur:
fp.write('\t<RECORD>\r\n')
for k in key_list:
v = item.get(k, '')
if v is None:
real_value = ''
else:
if type(v) == unicode:
real_value = cgi.escape(v)
else:
real_value = v
fp.write('\t\t<%s>%s</%s>\r\n' % (k, real_value, k))
fp.write('\t</RECORD>\r\n')
fp.write('</RECORDS>\r\n')
fp.close()
如需了解更多Python相关知识,可参考本站专题:《Python+MySQL数据库程序设计入门教程》、《Python常见数据库操作技巧汇总》、《Python数据结构与算法教程》、《Python Socket编程技巧总结》、《Python函数使用技巧总结》、《Python字符串操作技巧汇总》、《Python入门与进阶经典教程》及《Python文件与目录操作技巧汇总》。
希望上述内容能对读者的Python编程实践有所帮助。
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













