Python MySQL 查询到内存中的 CSV

0 投票
2 回答
702 浏览
提问于 2025-04-18 15:42

我有一个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'

撰写回答