Как добавить теги при загрузке на S3 с панд?Python

Программы на Python
Ответить
Anonymous
 Как добавить теги при загрузке на S3 с панд?

Сообщение Anonymous »

Pandas позволяет передавать путь AWS S3 непосредственно в .to_csv() и .to_parquet().
Существует аргумент Storage_options для передачи конкретных аргументов S3.< /p>
Я хотел бы вызвать .to_csv('s3://bucket/key.csv', Storage_options=something) и указать теги объекта S3 для применить к загруженному объекту как нечто.
Я прочитал документацию и не могу понять, как это сделать.
В документации по пандам нет списка возможные значения для Storage_options, они просто указывают на fsspec. Похоже, панды вызывают fsspec, который вызывает s3fs, который вызывает aiobotocore, который вызывает botocore, и который, вероятно, вызывает s3transfer. Как я могу передать аргументы тега S3 до конца этой кроличьей норы?
MWE

Код: Выделить всё

import pandas as pd
import boto3

bucket = 'mybucket' # change for your bucket
key = 'test/pandas/tags.csv'
tags = {'mytag': 'x'}

df = pd.DataFrame([{'a': 1}])
df.to_csv(f"s3://{bucket}/{key}") # try without any tags first
df.to_csv(f"s3://{bucket}/{key}", storage_options={'tags': tags})

resp = boto3.client('s3').get_object_tagging(Bucket=bucket, Key=key)
actual_tags = {t['Key']: t['Value'] for t in resp.get('TagSet', [])}
assert actual_tags == tags
ожидаемое поведение
Утверждение проходит. Объект S3 имеет тег mytag: x
фактическое поведение
Вторая строка .to_csv() терпит неудачу.
т.е. работает без тегов. Теги — это то, что вызывает сбой.

Код: Выделить всё

Traceback (most recent call last):
File "upld.py", line 9, in 
df.to_csv(f"s3://{bucket}/{key}", storage_options={'tags': tags})
File "/home/ec2-user/.pyenv/versions/3.8.11/lib/python3.8/site-packages/pandas/core/generic.py", line 3463, in to_csv
return DataFrameRenderer(formatter).to_csv(
File "/home/ec2-user/.pyenv/versions/3.8.11/lib/python3.8/site-packages/pandas/io/formats/format.py", line 1105, in to_csv
csv_formatter.save()
File "/home/ec2-user/.pyenv/versions/3.8.11/lib/python3.8/site-packages/pandas/io/formats/csvs.py", line 237, in save
with get_handle(
File "/home/ec2-user/.pyenv/versions/3.8.11/lib/python3.8/site-packages/pandas/io/common.py", line 608, in get_handle
ioargs = _get_filepath_or_buffer(
File "/home/ec2-user/.pyenv/versions/3.8.11/lib/python3.8/site-packages/pandas/io/common.py", line 357, in _get_filepath_or_buffer
file_obj = fsspec.open(
File "/home/ec2-user/.pyenv/versions/3.8.11/lib/python3.8/site-packages/fsspec/core.py", line 456, in open
return open_files(
File "/home/ec2-user/.pyenv/versions/3.8.11/lib/python3.8/site-packages/fsspec/core.py", line 299, in open_files
[fs.makedirs(parent, exist_ok=True) for parent in parents]
File "/home/ec2-user/.pyenv/versions/3.8.11/lib/python3.8/site-packages/fsspec/core.py", line 299, in 
[fs.makedirs(parent, exist_ok=True) for parent in parents]
File "/home/ec2-user/.pyenv/versions/3.8.11/lib/python3.8/site-packages/fsspec/asyn.py", line 91, in wrapper
return sync(self.loop, func, *args, **kwargs)
File "/home/ec2-user/.pyenv/versions/3.8.11/lib/python3.8/site-packages/fsspec/asyn.py", line 71, in sync
raise return_result
File "/home/ec2-user/.pyenv/versions/3.8.11/lib/python3.8/site-packages/fsspec/asyn.py", line 25, in _runner
result[0] = await coro
File "/home/ec2-user/.pyenv/versions/3.8.11/lib/python3.8/site-packages/s3fs/core.py", line 746, in _makedirs
await self._mkdir(path, create_parents=True)
File "/home/ec2-user/.pyenv/versions/3.8.11/lib/python3.8/site-packages/s3fs/core.py", line 731, in _mkdir
await self._call_s3("create_bucket", **params)
File "/home/ec2-user/.pyenv/versions/3.8.11/lib/python3.8/site-packages/s3fs/core.py", line 252, in _call_s3
await self.set_session()
File "/home/ec2-user/.pyenv/versions/3.8.11/lib/python3.8/site-packages/s3fs/core.py", line 395, in set_session
self.session = aiobotocore.session.AioSession(**self.kwargs)
TypeError: __init__() got an unexpected keyword argument 'tags'
Похоже, что эти аргументы передаются в экземпляр сеанса aiobotocore, а не в фактический вызов API S3 put_object из aiobotocore. Это заставляет меня думать, что это невозможно.
Альтернативы
Следует ли попробовать:

Код: Выделить всё

storage_options={
'tags': {
'k': 'v'
}
}
или

Код: Выделить всё

storage_options={
'tags': [
{'Key': 'k', 'Value': 'v'}
]
}
Конечно, я мог бы загрузить без тегов, а затем добавить теги отдельным вызовом бото.
Это не атомарно и стоит вдвое дороже (для небольших файлов).
Если бы существовал способ вернуть идентификатор версии из загрузки, это устранило бы некоторые проблемы параллелизма (параллельные записи).

Подробнее здесь: https://stackoverflow.com/questions/718 ... rom-pandas
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Python»