Uh oh!
There was an error while loading. Please reload this page.
This repository was archived by the owner on Mar 6, 2026. It is now read-only.
- Notifications
You must be signed in to change notification settings - Fork 325
fix: support ARRAY data type when loading from DataFrame with Parquet#980
Merged
gcf-merge-on-green
merged 22 commits into
googleapis:main
from
judahrand:dataframe-arraysOct 7, 2021
Uh oh!
There was an error while loading. Please reload this page.
Merged
Changes from all commits
Commits
Show all changes
22 commits
Select commit
Hold shift + click to select a range
62fd565
fix: use compliant Parquet by default
judahrand f44a6ae
chore: bump minimum `pyarrow` version
judahrand 8179ded
fix: default to `ParquetOptions.enable_list_inference is True`
judahrand bbdad5d
feat: detect `pyarrow.ListType` as `REPEATED`
judahrand 839004c
fix: add tests for arrays in DataFrames
judahrand 3cb2439
fix: add to system test to test `REPEATED` schema
judahrand 16b9fc0
fix: only use arg when `pyarrow>=4.0.0`
judahrand ba1b321
Revert "chore: bump minimum `pyarrow` version"
judahrand 5f915cd
chore: tidy up use of `_helpers.PYARROW_VERSIONS`
judahrand 1c52bb4
Add TODOs for move to V3
judahrand a452b31
Use `pyarrow` type testing function
judahrand ffb34a6
Add unit tests for `ParquetOptions`
judahrand d3828b1
Update docstring
judahrand 62137d8
Remove unused import
judahrand ba3f145
Remove user facing argument
judahrand ea54491
Fix doctring typo
judahrand e43c6fc
Merge branch 'main' into dataframe-arrays
judahrand d9c508c
Merge branch 'main' into dataframe-arrays
judahrand e8be400
Merge branch 'main' into dataframe-arrays
tswast 9ec8c67
Update google/cloud/bigquery/client.py
tswast 4fa8665
Update google/cloud/bigquery/client.py
tswast 4714b6c
Merge branch 'main' into dataframe-arrays
tswast File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Jump to file
Failed to load files.
Loading
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -27,19 +27,11 @@ | ||
| import json | ||
| import math | ||
| import os | ||
| import packaging.version | ||
| import tempfile | ||
| from typing import Any, BinaryIO, Dict, Iterable, Optional, Sequence, Tuple, Union | ||
| import uuid | ||
| import warnings | ||
| try: | ||
| import pyarrow | ||
| _PYARROW_VERSION = packaging.version.parse(pyarrow.__version__) | ||
| except ImportError: # pragma: NO COVER | ||
| pyarrow = None | ||
| from google import resumable_media # type: ignore | ||
| from google.resumable_media.requests import MultipartUpload | ||
| from google.resumable_media.requests import ResumableUpload | ||
| @@ -103,6 +95,10 @@ | ||
| from google.cloud.bigquery.table import TableListItem | ||
| from google.cloud.bigquery.table import TableReference | ||
| from google.cloud.bigquery.table import RowIterator | ||
| from google.cloud.bigquery.format_options import ParquetOptions | ||
| from google.cloud.bigquery import _helpers | ||
| pyarrow = _helpers.PYARROW_VERSIONS.try_import() | ||
| _DEFAULT_CHUNKSIZE = 100 * 1024 * 1024 # 100 MB | ||
| @@ -128,8 +124,6 @@ | ||
| # https://github.com/googleapis/python-bigquery/issues/438 | ||
| _MIN_GET_QUERY_RESULTS_TIMEOUT = 120 | ||
| # https://github.com/googleapis/python-bigquery/issues/781#issuecomment-883497414 | ||
| _PYARROW_BAD_VERSIONS = frozenset([packaging.version.Version("2.0.0")]) | ||
| TIMEOUT_HEADER = "X-Server-Timeout" | ||
| @@ -2469,10 +2463,10 @@ def load_table_from_dataframe( | ||
| They are supported when using the PARQUET source format, but | ||
| due to the way they are encoded in the ``parquet`` file, | ||
| a mismatch with the existing table schema can occur, so | ||
| 100% compatibility cannot be guaranteed for REPEATED fields when | ||
| REPEATED fields are not properly supported when using ``pyarrow<4.0.0`` | ||
| using the parquet format. | ||
| https://github.com/googleapis/python-bigquery/issues/17 | ||
| https://github.com/googleapis/python-bigquery/issues/19 | ||
| Args: | ||
| dataframe (pandas.DataFrame): | ||
| @@ -2519,18 +2513,18 @@ def load_table_from_dataframe( | ||
| :attr:`~google.cloud.bigquery.job.SourceFormat.PARQUET` are | ||
| supported. | ||
| parquet_compression (Optional[str]): | ||
| [Beta] The compression method to use if intermittently | ||
| serializing ``dataframe`` to a parquet file. | ||
| The argument is directly passed as the ``compression`` | ||
| argument to the underlying ``pyarrow.parquet.write_table()`` | ||
| method (the default value "snappy" gets converted to uppercase). | ||
| https://arrow.apache.org/docs/python/generated/pyarrow.parquet.write_table.html#pyarrow-parquet-write-table | ||
| If the job config schema is missing, the argument is directly | ||
| passed as the ``compression`` argument to the underlying | ||
| ``DataFrame.to_parquet()`` method. | ||
| https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.to_parquet.html#pandas.DataFrame.to_parquet | ||
| [Beta] The compression method to use if intermittently | ||
| serializing ``dataframe`` to a parquet file. | ||
| The argument is directly passed as the ``compression`` | ||
| argument to the underlying ``pyarrow.parquet.write_table()`` | ||
| method (the default value "snappy" gets converted to uppercase). | ||
| https://arrow.apache.org/docs/python/generated/pyarrow.parquet.write_table.html#pyarrow-parquet-write-table | ||
| If the job config schema is missing, the argument is directly | ||
| passed as the ``compression`` argument to the underlying | ||
| ``DataFrame.to_parquet()`` method. | ||
| https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.to_parquet.html#pandas.DataFrame.to_parquet | ||
| timeout (Optional[float]): | ||
| The number of seconds to wait for the underlying HTTP transport | ||
| before using ``retry``. | ||
| @@ -2562,6 +2556,16 @@ def load_table_from_dataframe( | ||
| if job_config.source_format is None: | ||
| # default value | ||
| job_config.source_format = job.SourceFormat.PARQUET | ||
| if ( | ||
| job_config.source_format == job.SourceFormat.PARQUET | ||
| and job_config.parquet_options is None | ||
| ): | ||
| parquet_options = ParquetOptions() | ||
| # default value | ||
| parquet_options.enable_list_inference = True | ||
tswast marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| job_config.parquet_options = parquet_options | ||
| if job_config.source_format not in supported_formats: | ||
| raise ValueError( | ||
| "Got unexpected source_format: '{}'. Currently, only PARQUET and CSV are supported".format( | ||
| @@ -2628,12 +2632,12 @@ def load_table_from_dataframe( | ||
| try: | ||
| if job_config.source_format == job.SourceFormat.PARQUET: | ||
| if _PYARROW_VERSION in _PYARROW_BAD_VERSIONS: | ||
| if _helpers.PYARROW_VERSIONS.is_bad_version: | ||
| msg = ( | ||
| "Loading dataframe data in PARQUET format with pyarrow " | ||
| f"{_PYARROW_VERSION} can result in data corruption. It is " | ||
| "therefore *strongly* advised to use a different pyarrow " | ||
| "version or a different source format. " | ||
| f"{_helpers.PYARROW_VERSIONS.installed_version} can result in data " | ||
| "corruption. It is therefore *strongly* advised to use a " | ||
| "different pyarrow version or a different source format. " | ||
| "See: https://github.com/googleapis/python-bigquery/issues/781" | ||
| ) | ||
| warnings.warn(msg, category=RuntimeWarning) | ||
| @@ -2647,9 +2651,19 @@ def load_table_from_dataframe( | ||
| job_config.schema, | ||
| tmppath, | ||
| parquet_compression=parquet_compression, | ||
| parquet_use_compliant_nested_type=True, | ||
| ) | ||
| else: | ||
| dataframe.to_parquet(tmppath, compression=parquet_compression) | ||
| dataframe.to_parquet( | ||
| tmppath, | ||
| engine="pyarrow", | ||
| compression=parquet_compression, | ||
| **( | ||
| {"use_compliant_nested_type": True} | ||
| if _helpers.PYARROW_VERSIONS.use_compliant_nested_type | ||
| else {} | ||
| ), | ||
| ) | ||
| else: | ||
Oops, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍