python 实现从mysql 导出为csv

接到如下需求:提供一个接口,把mysql 里面的item表 导出为csv,客户端 每天会请求这个接口 获取item 数据。

目前主要开发语言是java,用java 写当然没有问题,刚好最近再搞python 相关的东西,就想到用python 实现下。

1,选择web服务器
用的是 tornado,因为之前用到过这个
安装也很简单: http://demo.pythoner.com/itt2zh/
$ curl -L -O https://github.com/facebook/tornado/archive/v3.1.0.tar.gz
$ tar xvzf v3.1.0.tar.gz
$ cd tornado-3.1.0
$ python setup.py build
$ sudo python setup.py install

测试代码:
# !/usr/bin/env python
# -*- coding: utf-8 -*-

import tornado.ioloop
import tornado.web

class DownloadCSVHandler(tornado.web.RequestHandler):
        def get(self):
                self.write("hello python")

application = tornado.web.Application([
    (r"/hello", DownloadCSVHandler)
])

if __name__ == "__main__":
        application.listen(8866)
        tornado.ioloop.IOLoop.instance().start()
浏览器访问    http://localhost:8866/hello

2,安装MySQL-Python 驱动
用的较多的 MySQLdb ,官方下载地址,  https://pypi.python.org/pypi/MySQL-python/
但是在安装过程中,出现了各种问题,各种not found,no module,最后卡在EnvironmentError: mysql_config not found 这个错误,半天都没解决。
最后得知mysql 官方也出了个驱动MySQL Connector/Python,下载地址  http://dev.mysql.com/downloads/connector/python/,如果找不到对应的系统版本,就选择Platform Independent平台无关
安装: http://dev.mysql.com/doc/connector-python/en/connector-python-installation-source.html    
    $ tar xzf mysql-connector-python-2.1.3.tar.gz
    $ cd mysql-connector-python-2.1.3
    $ sudo python setup.py install

结合tornado,包括下载文件的代码:
# !/usr/bin/env python
# -*- coding: utf-8 -*-

import tornado.ioloop
import tornado.web
import mysql.connector

class DownloadCSVHandler(tornado.web.RequestHandler):
        def get(self):
                exportItem()
                self.set_header("Content-Type","text/csv,charset=UTF-8")
                buf_size = 1000
                global __filename
                with open(__filename, 'rb') as f:
                        while True:
                                data = f.read(buf_size)
                                if not data:
                                        break
                                self.write(data)
                self.finish()

__filename = "/home/py/static/item.csv"

application = tornado.web.Application([
    (r"/download/item.csv", DownloadCSVHandler)
])

def exportItem():
        config={'host':'host',
        'user':'root',
        'password':'pwd',
        'port':3306 ,
        'database':'product_center',
        'charset':'utf8'
        }
        try:
                conn = mysql.connector.connect(**config)
                cur = conn.cursor()
                global __filename
                cur.execute('select id,unit,name,barcode,price from item limit 10 into outfile ' + __filename + ';')
        except mysql.connector.Error, e:
                print "Mysql Error %d: %s" % (e.args[0], e.args[1])
        finally:
                cur.close()
                conn.close()

if __name__ == "__main__":
        application.listen(8866)
        tornado.ioloop.IOLoop.instance().start()
本地测试没有问题,但是部署到生产环境上去,却发现了一个问题,mysql 的 into outfile 语句导出数据库,只能导出到本地,有人可能会说,把python服     务部署在这台mysql服务器上不就得了,答案是no,因为这样做不安全,也不优雅,服务器架构是mysql 只对外开放3306端口。

3,代码生成csv 文件
不能通过mysql直接导出为csv的方式,那就代码生成csv文件。
最终代码:
# !/usr/bin/env python
# -*- coding: utf-8 -*-

import tornado.ioloop
import tornado.web
import mysql.connector
import time
import csv
import sys

reload(sys)
sys.setdefaultencoding('utf-8')

filename = "/home/py/static/item.csv"

class DownloadCSVHandler(tornado.web.RequestHandler):
        def get(self):
                setFileName()
                exportItem()
                self.set_header("Content-Type","text/csv,charset=UTF-8")
                buf_size = 1000
                with open(filename, 'rb') as f:
                        while True:
                                data = f.read(buf_size)
                                if not data:
                                        break
                                self.write(data)
                self.finish()

application = tornado.web.Application([
    (r"/download/item.csv", DownloadCSVHandler)

def setFileName():
        global filename
        filename = "/home/py/static/item" + time.strftime('%Y%m%d%H%M') + ".csv"

def exportItem():
        config={'host':'host',
        'user':'root',
        'password':'pwd',
        'port':3306 ,
        'database':'product',
        'charset':'utf8'
        }
        result = []
        try:
                conn = mysql.connector.connect(**config)
                cur = conn.cursor()
                cur.execute('select id,unit,name,barcode,price from item;')
                for res in cur:
                        result.append(res)
        except mysql.connector.Error, e:
                print "Mysql Error %d: %s" % (e.args[0], e.args[1])
        finally:
                cur.close()
                conn.close()
        if(len(result) >= 0):
                global filename
                with open(filename, 'wb') as csvfile:
                        spamwriter = csv.writer(csvfile)
                        #, delimiter=' ', quotechar=' ', quoting=csv.QUOTE_MINIMAL)
                        for res in result:
                        	spamwriter.writerow(res)

if __name__ == "__main__":
        application.listen(8866)
        tornado.ioloop.IOLoop.instance().start()
其实还可以考虑,通过mysqldump命令,远程导出数据库,应该可以实现,后面再尝试。
     
    

      


你可能感兴趣的:(python)