【发布时间】:2014-05-18 13:41:25
【问题描述】:
我正在编写一个脚本,我必须将 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 是什么?
【问题讨论】: