【问题标题】:Attach Pandas Dataframe as .csv in email Without using .to_csv在电子邮件中将 Pandas Dataframe 附加为 .csv 而不使用 .to_csv
【发布时间】:2020-12-04 21:37:17
【问题描述】:

我有一个 pandas 数据框,我想以 .csv 文件的形式在电子邮件附件中发送出去。所以现在当我使用 df.to_csv() 时,每次都会下载文件。

我不想将文件保存在系统中,而只想将其作为 .csv 文件直接传递。有没有办法做到这一点?

import pandas as pd

df = pd.DataFrame(output of sqlquery) # this data is dataframe output of a sql query. 

def send_email(sender, recipient, aws_region, subject, df):

client = boto3.client('ses', region_name=aws_region)

BODY_TEXT = "Hello,\r\nPlease find the attached file."
BODY_HTML = """\
<html>
<head></head>
<body>
<h1>Hello!</h1>
<p>Please find the attached file.</p>
</body>
</html>
"""

msg = MIMEMultipart('mixed')
msg['From'] = sender
print(msg['From'])
msg['To'] = recipient
msg['Subject'] = 'TOI Order Alert'

# The character encoding for the email.
CHARSET = "UTF-8"

msg_body = MIMEMultipart('alternative')
textpart = MIMEText(BODY_TEXT.encode(CHARSET), 'plain', CHARSET)
htmlpart = MIMEText(BODY_HTML.encode(CHARSET), 'html', CHARSET)


# Add the text and HTML parts to the child container.
msg_body.attach(textpart)
msg_body.attach(htmlpart)





# # Define the attachment part and encode it using MIMEApplication.
att = MIMEApplication(df.to_csv('test.csv'))
att.add_header('Content-Disposition','attachment; filename='+ 'test.csv')

# Attach the multipart/alternative child container to the multipart/mixed
# parent container.
msg.attach(msg_body)

# Add the attachment to the parent container.
msg.attach(att)



#Provide the contents of the email.
response = client.send_raw_email(
        Source=msg['From'],
        Destinations=[
            msg['To']
        ],
        RawMessage={
            'Data':msg.as_string(),
        }
    )
 

【问题讨论】:

  • 一般情况下,当我需要这样做时,我会通过将附件保存为临时文件来完成,当它的分数完成时它会被自动删除。您可以查看文档。评估一次,它是否符合您的要求。 docs.python.org/3/library/tempfile.html
  • @mohit 我正在尝试通过 ses 发送文件,但超出了 10mb 的限制。关于如何发送或压缩文件的任何想法?
  • 您可以压缩它并尝试发送它,但最好将其存储在 S3 中并在电子邮件中提供一个公开的或预签名的、有时间限制的 URL。

标签: python pandas amazon-web-services aws-lambda


【解决方案1】:

我建议如下

import io

s_buf = io.StringIO() 
df.to_csv(s_buf)
byte_buf = s_buf.encode()

并传入字节缓冲区

【讨论】:

  • 这是为什么呢?这仍然迫使我将 df 保存到我的本地数据库中。我试图不这样做。
  • 您想避免在本地文件系统上生成 csv?如果是这种情况,StringIO 将创建一个包含 csv 文件的内存缓冲区。然后你可以沿着任何八位字节流发送它
  • 知道了,所以我的新代码是: s_buf = io.BytesIO() df.to_csv(s_buf) # # 定义附件部分并使用 MIMEApplication 对其进行编码。 att = MIMEApplication(EXPORTERS['dataframe.csv'](df)) att= MIMEApplication(s_buf) 不幸的是,我仍然收到一条失败消息:“errorMessage”:“需要一个类似字节的对象,而不是'str'”,
  • 我已经更新了我的答案并将字符串转换为类似对象的字节。
  • 新错误:“errorMessage”:“没有字符串参数的编码”,
猜你喜欢
  • 2020-12-04
  • 1970-01-01
  • 2014-02-20
  • 2015-03-06
  • 1970-01-01
  • 2021-01-08
  • 2017-07-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多