|
12 | 12 | BIGQUERY_INSTALLED_VERSION = None
|
13 | 13 | SHOW_VERBOSE_DEPRECATION = False
|
14 | 14 | SHOW_PRIVATE_KEY_DEPRECATION = False
|
15 |
| -USE_TZAWARE_TIMESTAMP = False |
16 | 15 | PRIVATE_KEY_DEPRECATION_MESSAGE = (
|
17 | 16 | "private_key is deprecated and will be removed in a future version."
|
18 | 17 | "Use the credentials argument instead. See "
|
|
27 | 26 |
|
28 | 27 |
|
29 | 28 | def _check_google_client_version():
|
30 |
| - global BIGQUERY_INSTALLED_VERSION, SHOW_VERBOSE_DEPRECATION, SHOW_PRIVATE_KEY_DEPRECATION, USE_TZAWARE_TIMESTAMP |
| 29 | + global BIGQUERY_INSTALLED_VERSION, SHOW_VERBOSE_DEPRECATION, SHOW_PRIVATE_KEY_DEPRECATION |
31 | 30 |
|
32 | 31 | try:
|
33 | 32 | import pkg_resources
|
@@ -62,12 +61,6 @@ def _check_google_client_version():
|
62 | 61 | SHOW_PRIVATE_KEY_DEPRECATION = (
|
63 | 62 | pandas_installed_version >= pandas_version_with_credentials_arg
|
64 | 63 | )
|
65 |
| - pandas_version_supporting_tzaware_dtype = pkg_resources.parse_version( |
66 |
| - "0.24.0" |
67 |
| - ) |
68 |
| - USE_TZAWARE_TIMESTAMP = ( |
69 |
| - pandas_installed_version >= pandas_version_supporting_tzaware_dtype |
70 |
| - ) |
71 | 64 |
|
72 | 65 |
|
73 | 66 | def _test_google_api_imports():
|
@@ -501,8 +494,8 @@ def run_query(self, query, **kwargs):
|
501 | 494 | if df.empty:
|
502 | 495 | df = _cast_empty_df_dtypes(schema_fields, df)
|
503 | 496 |
|
504 |
| - if not USE_TZAWARE_TIMESTAMP: |
505 |
| - df = _localize_df(schema_fields, df) |
| 497 | + # Ensure any TIMESTAMP columns are tz-aware. |
| 498 | + df = _localize_df(schema_fields, df) |
506 | 499 |
|
507 | 500 | logger.debug("Got {} rows.\n".format(rows_iter.total_rows))
|
508 | 501 | return df
|
@@ -662,20 +655,14 @@ def _bqschema_to_nullsafe_dtypes(schema_fields):
|
662 | 655 | See: http://pandas.pydata.org/pandas-docs/dev/missing_data.html
|
663 | 656 | #missing-data-casting-rules-and-indexing
|
664 | 657 | """
|
665 |
| - import pandas.api.types |
666 |
| - |
667 |
| - # pandas doesn't support timezone-aware dtype in DataFrame/Series |
668 |
| - # constructors until 0.24.0. See: |
669 |
| - # https://github.com/pandas-dev/pandas/issues/25843#issuecomment-479656947 |
670 |
| - timestamp_dtype = "datetime64[ns]" |
671 |
| - if USE_TZAWARE_TIMESTAMP: |
672 |
| - timestamp_dtype = pandas.api.types.DatetimeTZDtype(unit="ns", tz="UTC") |
673 |
| - |
674 | 658 | # If you update this mapping, also update the table at
|
675 | 659 | # `docs/source/reading.rst`.
|
676 | 660 | dtype_map = {
|
677 | 661 | "FLOAT": np.dtype(float),
|
678 |
| - "TIMESTAMP": timestamp_dtype, |
| 662 | + # pandas doesn't support timezone-aware dtype in DataFrame/Series |
| 663 | + # constructors. It's more idiomatic to localize after construction. |
| 664 | + # https://github.com/pandas-dev/pandas/issues/25843 |
| 665 | + "TIMESTAMP": "datetime64[ns]", |
679 | 666 | "TIME": "datetime64[ns]",
|
680 | 667 | "DATE": "datetime64[ns]",
|
681 | 668 | "DATETIME": "datetime64[ns]",
|
@@ -734,7 +721,7 @@ def _localize_df(schema_fields, df):
|
734 | 721 | if field["mode"].upper() == "REPEATED":
|
735 | 722 | continue
|
736 | 723 |
|
737 |
| - if field["type"].upper() == "TIMESTAMP": |
| 724 | + if field["type"].upper() == "TIMESTAMP" and df[column].dt.tz is None: |
738 | 725 | df[column] = df[column].dt.tz_localize("UTC")
|
739 | 726 |
|
740 | 727 | return df
|
|
0 commit comments