Skip to content

Commit 02754a5

Browse files
authored
Fix Parquet UNKNOWN annotation IT writes on Dataproc[databricks] (NVIDIA#15428)
fixes NVIDIA#15426. ### Description - Dataproc nightlies failed in `test_parquet_unknown_type_annotation_pre_411_physical` because PyArrow wrote directly to `spark_tmp_path`, which is created via Hadoop `FileSystem.mkdirs` (GCS on Dataproc) rather than the local filesystem; write the sample Parquet file locally and `copy_from_local` into the Hadoop path so cluster reads succeed. - Move the existing `copy_from_local` helper from `fastparquet_compatibility_test.py` into `parquet_test_utils.py` and reuse it from both call sites to avoid duplicating the Hadoop copy path. ### Checklists Documentation - [ ] Updated for new or modified user-facing features or behaviors - [x] No user-facing change Testing - [x] Added or modified tests to cover new code paths - [ ] Covered by existing tests (Please provide the names of the existing tests in the PR description.) - [ ] Not required Performance - [ ] Tests ran and results are added in the PR description - [ ] Issue filed with a link in the PR description - [x] Not required Signed-off-by: Firestarman <firestarmanllc@gmail.com>
1 parent 6f42817 commit 02754a5

3 files changed

Lines changed: 26 additions & 14 deletions

File tree

integration_tests/src/main/python/fastparquet_compatibility_test.py

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
from asserts import assert_gpu_and_cpu_are_equal_collect
1818
from data_gen import *
1919
from fastparquet_utils import get_fastparquet_result_canonicalizer
20+
from parquet_test_utils import copy_from_local
2021
from spark_session import is_databricks_runtime, spark_version, with_cpu_session, with_gpu_session
2122

2223

@@ -247,17 +248,6 @@ def test_reading_file_written_with_gpu(spark_tmp_path, column_gen):
247248
delete_local_directory(local_base_path)
248249

249250

250-
def copy_from_local(spark, local_source, hdfs_target):
251-
"""
252-
Copies contents of local_source to hdfs_target.
253-
"""
254-
sc = spark.sparkContext
255-
Path = sc._jvm.org.apache.hadoop.fs.Path
256-
config = sc._jsc.hadoopConfiguration()
257-
fs = sc._jvm.org.apache.hadoop.fs.FileSystem.get(config)
258-
fs.copyFromLocalFile(Path(local_source), Path(hdfs_target))
259-
260-
261251
@pytest.mark.skipif(condition=fastparquet_unavailable(),
262252
reason="fastparquet is required for testing fastparquet compatibility")
263253
@pytest.mark.parametrize('column_gen', [

integration_tests/src/main/python/parquet_test.py

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
# limitations under the License.
1414
import os
1515
import re
16+
import shutil
17+
import tempfile
1618

1719
import pytest
1820

@@ -23,7 +25,7 @@
2325
from marks import *
2426
import pyarrow as pa
2527
import pyarrow.parquet as pq
26-
from parquet_test_utils import parquet_row_group_midpoints
28+
from parquet_test_utils import copy_from_local, parquet_row_group_midpoints
2729
from pyspark.sql.types import *
2830
from pyspark.sql.functions import *
2931
from spark_init_internal import spark_version
@@ -1996,7 +1998,12 @@ def setup_table(spark):
19961998

19971999
def _write_parquet_unknown_null_table(
19982000
data_path, with_list=False, with_map=False, field_id=None):
1999-
"""Write INT32 physical + UNKNOWN/Null logical annotation (Spark void_in_parquet shape)."""
2001+
"""Write INT32 physical + UNKNOWN/Null logical annotation (Spark void_in_parquet shape).
2002+
2003+
PyArrow writes only to the local filesystem, while spark_tmp_path is created via
2004+
Hadoop FileSystem.mkdirs. On Dataproc the default FS is typically GCS, so writing
2005+
directly to data_path fails with FileNotFoundError. Write locally then copy.
2006+
"""
20002007
if with_list:
20012008
table = pa.table({
20022009
'list_void': pa.array([[None, None], [None], None], type=pa.list_(pa.null())),
@@ -2018,7 +2025,13 @@ def _write_parquet_unknown_null_table(
20182025
'id': pa.array([1, 2, 3], type=pa.int32()),
20192026
'void_col': pa.array([None, None, None], type=pa.null()),
20202027
})
2021-
pq.write_table(table, data_path)
2028+
local_dir = tempfile.mkdtemp(prefix='parquet_unknown_')
2029+
try:
2030+
local_file = os.path.join(local_dir, 'part.parquet')
2031+
pq.write_table(table, local_file)
2032+
with_cpu_session(lambda spark: copy_from_local(spark, local_file, data_path))
2033+
finally:
2034+
shutil.rmtree(local_dir, ignore_errors=True)
20222035

20232036

20242037
# SPARK-56045 / SPARK-54220: Parquet UNKNOWN logical type annotation. PyArrow null columns are

integration_tests/src/main/python/parquet_test_utils.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,15 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15+
def copy_from_local(spark, local_source, hdfs_target):
16+
"""Copy a local path onto the Hadoop FS used by spark_tmp_path (e.g. GCS on Dataproc)."""
17+
sc = spark.sparkContext
18+
Path = sc._jvm.org.apache.hadoop.fs.Path
19+
config = sc._jsc.hadoopConfiguration()
20+
fs = sc._jvm.org.apache.hadoop.fs.FileSystem.get(config)
21+
fs.copyFromLocalFile(Path(local_source), Path(hdfs_target))
22+
23+
1524
def parquet_row_group_midpoints(spark, path):
1625
"""Returns an approximate byte midpoint for each Parquet row group."""
1726
jvm = spark.sparkContext._jvm

0 commit comments

Comments
 (0)