Python MySQL 查询到内存中的 CSV
我有一个Python脚本,它会查询数据库,然后把结果通过邮件发出去。目前这个脚本是这样的(请原谅我对Python还不太熟悉)
db = mdb.connect(db_host, db_user, db_pass, db_name)
cur = db.cursor()
dbQuery = ("SELECT A, B, C from table")
cur.execute (dbQuery)
rows = cur.fetchall()
fp = open(filename,'w')
myFile = csv.writer(fp, quotechar='"', quoting=csv.QUOTE_ALL)
myFile.writerows(rows)
fp.close()
msg = MIMEMultipart()
msg['Subject'] = subject
msg['From'] = email_from
msg['To'] = email_to
body = MIMEMultipart('alternative')
body.attach(MIMEText(content, 'plain' ))
part = MIMEBase('application', "octet-stream")
part.set_payload(open(filename, "rb").read())
Encoders.encode_base64(part)
part.add_header('Content-Disposition', 'attachment', filename=filename)
msg.attach(body)
msg.attach(part)
server = smtplib.SMTP(smtp_server)
server.sendmail(email_from, email_to, msg.as_string())
我意识到把CSV文件存储在硬盘上,然后再关闭它再打开来读取,这样做效率不高。我该怎么把这些操作都放在内存中进行呢?其实没有必要把CSV保存下来,因为数据都在数据库里。
2 个回答
2
使用一个 SpooledTemporaryFile
。这个东西就像一个文件,但它是存放在内存里的(除非它变得非常大,这时候它会自动转换成一个临时文件)。
fp = tempfile.SpooledTemporaryFile()
myFile = csv.writer(fp, quotechar='"', quoting=csv.QUOTE_ALL)
myFile.writerows(rows)
fp.seek(0) # rewind the file handle
...
part.set_payload(fp.read())
1
你可以使用 cStringIO
这个工具。
# create an in-memory "file":
f = cStringIO.StringIO()
# attach it to a writer:
w = csv.writer(f)
# write something:
w.writerows([[1,2,3],[4,5,6],[7,8,9]])
# read the content:
content = f.getvalue()
'1,2,3\r\n4,5,6\r\n7,8,9\r\n'