s3Hook load_file_obj FileObj必须实现读取错误

时间:2019-08-16 00:33:31

标签: python amazon-s3 airflow

我已经尝试了所有可以找到和想到的东西,但是似乎无法正确执行此代码。 我正在使用Airflow,尝试运行SQL select语句,返回结果,然后使用s3将结果直接上传到PythonCallable task

我无法在本地将DataFrame保存为csv,所以这不是一种选择。 最终,我继续循环回到此ERROR - Fileobj must implement read。唯一的“成功”尝试在我的s3文件中产生了空结果。我尝试使用在另一篇文章中找到的.seek(0)方法,但后来得到ERROR - Unicode-objects must be encoded before hashing。无论如何,下面是我的代码。任何方向都深表感谢。


    snow_hook = SnowflakeHook(
        snowflake_conn_id='Snowflake_ETL_vault'
    )
    df = snow_hook.get_pandas_df(sql=sql)
    with io.StringIO() as stream:
        df.to_csv(stream)
        stream.seek(0)
        f = stream.getvalue()

        s3_hook = S3Hook(aws_conn_id='s3_analytics')
        s3_hook.load_file_obj(
            file_obj=f,
            bucket_name=bkt,
            key=key,
            replace=True
        )

编辑:我也尝试过f = stream.read(),但仍然以某种方式获取Fileobj必须实现读取。

谢谢!

2 个答案:

答案 0 :(得分:1)

我也面临同样的问题,花了一些时间来理解问题的本质。

出现错误-Fileobj必须实现读取的原因是file_obj期望流对象本身不是stream.getvalue()

pandas.to_csv遇到一些编码问题,您可以在此处找到问题详细信息 https://github.com/pandas-dev/pandas/issues/23854

解决方法是使用s3hook中的load_bytes函数写入字节

with io.BytesIO() as buffer:                                
    buffer.write(
        bytes(
            df.to_csv(None, sep="|", quotechar='"'),
            encoding="utf-8"
        )
    )               
    hook.load_bytes(
        buffer.getvalue(),
        bucket_name="bucket_name",
        key="keyname.csv", 
        replace=True
    )

尽管如此,我仍在寻找更好的解决方案

答案 1 :(得分:0)

您可以通过load_string命令来完成操作

        df = snow_hook.get_pandas_df(sql=sql)
        csv_data_as_str = df.to_csv(index=False)
        s3_hook.load_string(string_data=csv_data_as_str, key=s3_key, bucket_name=s3_bucket, replace=True)