Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 4.3k
ARROW-15892: [C++] Dataset APIs require s3:ListBucket Permissions#12701
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Uh oh!
There was an error while loading. Please reload this page.
Changes from all commits
0c6002f0b8902b3473c51472cac72ff62339f63cd5f6a01ae21dba25a40aef03c00819587bb3efc39613165260658a0e51ab9a792bd28ec183aecbde181b9d9ae65f3b1ece5f247bec20d6e0feFile filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -753,7 +753,7 @@ def write_dataset(data, base_dir, basename_template=None, format=None, | ||
| max_partitions=None, max_open_files=None, | ||
| max_rows_per_file=None, min_rows_per_group=None, | ||
| max_rows_per_group=None, file_visitor=None, | ||
| existing_data_behavior='error'): | ||
| existing_data_behavior='error', create_dir=True): | ||
sanjibansg marked this conversation as resolved.
Outdated
Uh oh!There was an error while loading. Please reload this page. | ||
| """ | ||
| Write a dataset to a given format and partitioning. | ||
| @@ -852,6 +852,9 @@ def file_visitor(written_file): | ||
| dataset. The first time each partition directory is encountered | ||
| the entire directory will be deleted. This allows you to overwrite | ||
| old partitions completely. | ||
| create_dir : bool, default True | ||
| If False, directories will not be created. This can be useful for | ||
| filesystems that do not require directories. | ||
| """ | ||
| from pyarrow.fs import _resolve_filesystem_and_path | ||
| @@ -928,5 +931,5 @@ def file_visitor(written_file): | ||
| scanner, base_dir, basename_template, filesystem, partitioning, | ||
| file_options, max_partitions, file_visitor, existing_data_behavior, | ||
| max_open_files, max_rows_per_file, | ||
| min_rows_per_group, max_rows_per_group | ||
| min_rows_per_group, max_rows_per_group, create_dir | ||
| ) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -35,7 +35,8 @@ | ||
| import pyarrow.feather | ||
| import pyarrow.fs as fs | ||
| from pyarrow.tests.util import (change_cwd, _filesystem_uri, | ||
| FSProtocolClass, ProxyHandler) | ||
| FSProtocolClass, ProxyHandler, | ||
| _configure_s3_limited_user) | ||
| try: | ||
| import pandas as pd | ||
| @@ -4334,6 +4335,71 @@ def test_write_dataset_s3(s3_example_simple): | ||
| assert result.equals(table) | ||
| _minio_put_only_policy = """{ | ||
| "Version": "2012-10-17", | ||
| "Statement": [ | ||
| { | ||
| "Effect": "Allow", | ||
| "Action": [ | ||
| "s3:PutObject", | ||
| "s3:ListBucket", | ||
| "s3:GetObjectVersion" | ||
| ], | ||
| "Resource": [ | ||
| "arn:aws:s3:::*" | ||
| ] | ||
| } | ||
| ] | ||
| }""" | ||
| @pytest.mark.parquet | ||
| @pytest.mark.s3 | ||
| def test_write_dataset_s3_put_only(s3_server): | ||
| # [ARROW-15892] Testing the create_dir flag which will restrict | ||
| # creating a new directory for writing a dataset. This is | ||
| # required while writing a dataset in s3 where we have very | ||
| # limited permissions and thus we can directly write the dataset | ||
| # without creating a directory. | ||
| from pyarrow.fs import S3FileSystem | ||
| # write dataset with s3 filesystem | ||
| host, port, _, _ = s3_server['connection'] | ||
| fs = S3FileSystem( | ||
| access_key='limited', | ||
| secret_key='limited123', | ||
| endpoint_override='{}:{}'.format(host, port), | ||
| scheme='http' | ||
| ) | ||
| _configure_s3_limited_user(s3_server, _minio_put_only_policy) | ||
| table = pa.table([ | ||
| pa.array(range(20)), pa.array(np.random.randn(20)), | ||
| pa.array(np.repeat(['a', 'b'], 10))], | ||
| names=["f1", "f2", "part"] | ||
| ) | ||
| part = ds.partitioning(pa.schema([("part", pa.string())]), flavor="hive") | ||
| # writing with filesystem object with create_dir flag set to false | ||
sanjibansg marked this conversation as resolved.
Outdated
Uh oh!There was an error while loading. Please reload this page. | ||
| ds.write_dataset( | ||
| table, "existing-bucket", filesystem=fs, | ||
| format="feather", create_dir=False, partitioning=part, | ||
| existing_data_behavior='overwrite_or_ignore' | ||
| ) | ||
Member There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This test doesn't do any partitioning? ContributorAuthor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think we can use Hive or Directory partitioning here, as we are keeping the Member There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm, if we can't do anything else than filename partitioning then is it worth fixing this issue? @westonpace What do you think? Member There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As for the filename partioning bug, better to file a separate JIRA IMHO. Member There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The original ask was for a case that didn't have any partitioning. If an S3 user has a partitioning then they shouldn't run into the original issue because all CreateDir calls will be for bucket + path. So this flag is only to enable the very specific case where partitioning is not used. That being said, I think hive & directory partitioning should still work with We could also solve this problem by modifying s3fs.cc so that it didn't try and create the bucket if it already existed. This would add a Member There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I see. So should we add a test to check that it works anyway? ContributorAuthor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have modified the test to use Hive partitioning with the | ||
| # check roundtrip | ||
| result = ds.dataset( | ||
| "existing-bucket", filesystem=fs, format="ipc", partitioning="hive" | ||
| ).to_table() | ||
| assert result.equals(table) | ||
| with pytest.raises(OSError, match="Access Denied"): | ||
| ds.write_dataset( | ||
| table, "existing-bucket", filesystem=fs, | ||
| format="feather", create_dir=True, | ||
| existing_data_behavior='overwrite_or_ignore' | ||
| ) | ||
| @pytest.mark.parquet | ||
| def test_dataset_null_to_dictionary_cast(tempdir, dataset_reader): | ||
| # ARROW-12420 | ||
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.