我已经尝试了所有可以找到和想到的东西,但是似乎无法正确执行此代码。
我正在使用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必须实现读取。
谢谢!
答案 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)