Прикрепите фрейм данных Pandas в формате .csv в электронном письме без использования .to_csv

#python #pandas #amazon-web-services #aws-lambda

#python #pandas #amazon-веб-сервисы #aws-lambda

Вопрос:

У меня есть фрейм данных 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,rnPlease 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(),
        }
    )
 
  

Комментарии:

1. Обычно, когда мне нужно это сделать, я делаю это, сохраняя вложение как временный файл, и я. оно будет автоматически удалено, когда оценка будет завершена. Вы можете посмотреть документацию. Оцените один раз, соответствует ли это вашим требованиям или нет. docs.python.org/3/library/tempfile.html

2. @mohit Я пытаюсь отправить файл через ses и я нарушаю ограничение в 10 МБ. Есть идеи о том, как я все еще могу отправить это или сжать файл?

3. Вы можете сжать его и попробовать отправить, но лучше было бы сохранить его в S3 и указать общедоступный или предварительно подписанный URL-адрес с ограниченным сроком действия в электронном письме.

Ответ №1:

Я бы предложил следующее

 import io

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

И передайте в буфер байтов

Комментарии:

1. Почему это? Это все еще вынуждает меня сохранять df в моей локальной базе данных. Я пытаюсь этого не делать.

2. Вы хотите избежать генерации csv в локальной файловой системе? Если это так, StringIO создаст буфер в памяти, содержащий файл csv. Затем вы можете отправить его по любому октетному потоку

3. Понял, поэтому мой новый код выглядит так: s_buf = io.BytesIO() df.to_csv(s_buf) # # Определите часть вложения и закодируйте ее с помощью MIMEApplication. att = MIMEApplication(EXPORTERS[‘dataframe.csv’](df)) att= MIMEApplication(s_buf) К сожалению, я все еще получаю сообщение об ошибке: «ErrorMessage»: «требуется объект, подобный байтам, а не ‘str'»,

4. Я обновил свой ответ и преобразовал строку в объект, подобный байту.

5. Новая ошибка: «ErrorMessage»: «кодирование без строкового аргумента»,