在python中模拟类似文件的行为

时间:2014-05-18 13:41:26

标签: python sql file ftp

我正在编写脚本,我必须将SQL数据库中的一些表格转储到文件中,然后通过FTP传输。

因为转储可能变得非常大,我的想法是编写一个FakeFile,它在readline方法中从游标中逐行查询并将其传递给ftplib.FTP.storlines

这是我到目前为止所做的:

import ftplib
import MySQLdb

def MySQLFakeFile(object):
    '''
    Simulates a read-only file, which dumps rows on demand.
    Use this, to pass it to the FTP protocol to make the dump more efficient, 
    without the need to dump it somewhere and copy it over the net afterwords 
    '''
    def __init__(self, cursor, delimeter, table_name, query):
        self.cursor = cursor
        self.delimeter = delimeter
        self.table_name = table_name
        #query is something along select ... FROM %s
        self.cursor.execute(query, table_name)
        self._has_written_index = False
        #file attrs
        self.closed = False
        self.name = table_name + ".csv"
        self.encoding = "utf-8"
        self.mode = "r"


    def close(self):
        self.cursor.close()
        self.closed = True

    def flush(self):
        '''No-OP'''
        pass

    def read(self, size):
        pass

    def readline(self, size):
        if not self._has_written_index:
            ret = []
            for desc in self.cursor.description:
                ret.append(desc[0])
            self._has_written_index = True
        else:
            ret = self.cursor.fetchone()
        if not ret:
            return None

        s = ""
        for col in ret:
            s += str(col) + self.delimeter
        return s + "\n"

    def readlines(self, size):
        ret = []
        line = self.readline()
        while line:
            ret.append(line)
            line = self.readline()

    def write(self, string):
        raise Exception("cannot write to a MySQLFakeFile")

    def writelines(self, lines)
        raise Exception("cannot write to a MySQLFakeFile")

db = MySQLdb("host", "user", "pass", "db")
ftp = ftplib.FTP("host", "user", "pass")
fakeFile = MySQLFakeFile(db.cursor(), ";", "tableName", "SELECT * FROM %s")
ftp.storlines("STOR tableName.csv", fakeFile)

给了我

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.7/ftplib.py", line 496, in storlines
    if len(buf) > self.maxline:
TypeError: object of type 'NoneType' has no len()

我做错了什么,这里的NoneType是什么?

1 个答案:

答案 0 :(得分:1)

当到达行尾时,您的readline会返回None而不是空字符串""

您的readlines什么都不返回。

def readlines(self, size):
    ret = []
    while True:
        line = self.readline()
        if not line:
            break
        ret.append(line)
    return ret