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

在python中模拟类似文件的行为,python,sql,file,ftp,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

我正在编写一个脚本,其中我必须将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()
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
文件“/usr/lib/python2.7/ftplib.py”,第496行,在storlines中
如果len(buf)>self.maxline:
TypeError:类型为“NoneType”的对象没有len()

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

当到达行末尾时,您的读线返回
None
,而不是空字符串

您的readlines不返回任何内容

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