Eu tenho um DataFrame do pandas que desejo enviar para um novo arquivo CSV. O problema é que não quero salvar o arquivo localmente antes de transferi-lo para o s3. Existe algum método como to_csv para gravar o dataframe em s3 diretamente? Estou usando o boto3.
Aqui está o que tenho até agora:
import boto3
s3 = boto3.client('s3', aws_access_key_id='key', aws_secret_access_key='secret_key')
read_file = s3.get_object(Bucket, Key)
df = pd.read_csv(read_file['Body'])
# Make alterations to DataFrame
# Then export DataFrame to CSV through direct transfer to s3
df.to_csv('s3://mybucket/dfs/somedf.csv')
. stackoverflow.com/a/56275519/908886 para mais informações.Respostas:
Você pode usar:
fonte
TypeError: unicode argument expected, got 'str'
erro ao usarStringIO
. UseiBytesIO
e funcionou perfeitamente bem. Observação: isso foi em Python 2.7bucket
objeto? como você criou isso?bucket
é onde você armazena objetos no S3. O código assume que você já criou o destino (pense: diretório) onde armazená-lo. Ver S3 docsVocê pode usar diretamente o caminho S3. Estou usando o Pandas 0.24.1
Nota de lançamento:
fonte
NoCredentialsError: Unable to locate credentials
. Alguma sugestão?NotImplementedError: Text mode not supported, use mode='wb' and manage bytes
. alguma sugestão?Eu gosto do s3fs, que permite que você use o s3 (quase) como um sistema de arquivos local.
Você consegue fazer isso:
s3fs
suporta apenasrb
ewb
modos de abrir o arquivo, é por isso que fiz issobytes_to_write
.fonte
s3fs
não parece suportar o modo de acréscimo.Esta é uma resposta mais atualizada:
O problema com o StringIO é que ele vai consumir sua memória. Com este método, você está transmitindo o arquivo para s3, em vez de convertê-lo em string e, em seguida, gravá-lo em s3. Manter o dataframe do pandas e sua cópia da string na memória parece muito ineficiente.
Se você estiver trabalhando em um instante ec2, poderá atribuir a ele uma função IAM para permitir gravá-lo em s3, portanto, não é necessário passar credenciais diretamente. No entanto, você também pode se conectar a um intervalo passando credenciais para a
S3FileSystem()
função. Veja a documentação: https://s3fs.readthedocs.io/en/latest/fonte
to_csv()
. parece uma implementação mais limpa.botocore.exceptions.ClientError: An error occurred (AccessDenied) when calling the PutObject operation: Access Denied
... Eu até mesmo fiz o intervalo PUBLIC READ e adicionei as seguintes ações, sob minha conta específica de usuário IAM, na Política do"Action": [ "s3:PutObject", "s3:PutObjectAcl", "s3:GetObject", "s3:GetObjectAcl", "s3:DeleteObject" ]
def send_to_bucket(df, fn_out, bucketname): csv_buffer = StringIO(); df.to_csv(csv_buffer); s3_resource = boto3.resource('s3'); s3_resource.Object(bucketname, fn_out).put(Body=csv_buffer.getvalue());
Se passar
None
como primeiro argumentoto_csv()
os dados serão devolvidos como string. A partir daí, é uma etapa fácil fazer o upload para o S3 de uma vez.Também deve ser possível passar um
StringIO
objeto parato_csv()
, mas usar uma string será mais fácil.fonte
None
parato_csv()
e usar a string retornada do que é criar umStringIO
objeto e, em seguida, ler novamente os dados para fora.Você também pode usar o AWS Data Wrangler :
Observe que ele será dividido em várias partes, uma vez que carrega em paralelo.
fonte
Descobri que isso pode ser feito usando
client
também e não apenasresource
.fonte
já que você está usando
boto3.client()
, tente:fonte
Encontrei uma solução muito simples que parece estar funcionando:
Espero que ajude !
fonte
Eu li um csv com duas colunas do intervalo s3 e o conteúdo do arquivo csv eu coloquei no dataframe do pandas.
Exemplo:
config.json
cls_config.json
cls_pandas.py
cls_s3.py
test.py
fonte