From 0aea359157574ebf85bd05b728365f149aba9b83 Mon Sep 17 00:00:00 2001 From: Patrick Hoefler Date: Fri, 24 Mar 2023 15:57:23 -0400 Subject: [PATCH 1/2] BUG: to_sql raises when arrow dtype has missing values --- pandas/core/arrays/arrow/array.py | 2 +- pandas/tests/io/test_sql.py | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/pandas/core/arrays/arrow/array.py b/pandas/core/arrays/arrow/array.py index 353da80e27464..b9508795e3c8e 100644 --- a/pandas/core/arrays/arrow/array.py +++ b/pandas/core/arrays/arrow/array.py @@ -2093,7 +2093,7 @@ def _dt_round( def _dt_to_pydatetime(self): data = self._pa_array.to_pylist() if self._dtype.pyarrow_dtype.unit == "ns": - data = [ts.to_pydatetime(warn=False) for ts in data] + data = [None if isna(ts) else ts.to_pydatetime(warn=False) for ts in data] return np.array(data, dtype=object) def _dt_tz_localize( diff --git a/pandas/tests/io/test_sql.py b/pandas/tests/io/test_sql.py index 1bfc5cf0c3178..ab88e4ccd8b82 100644 --- a/pandas/tests/io/test_sql.py +++ b/pandas/tests/io/test_sql.py @@ -570,6 +570,22 @@ def test_dataframe_to_sql_arrow_dtypes(conn, request): df.to_sql("test_arrow", conn, if_exists="replace", index=False) +@pytest.mark.db +@pytest.mark.parametrize("conn", all_connectable) +def test_dataframe_to_sql_arrow_dtypes_missing(conn, request, nulls_fixture): + # GH 52046 + pytest.importorskip("pyarrow") + df = DataFrame( + { + "datetime": pd.array( + [datetime(2023, 1, 1), nulls_fixture], dtype="timestamp[ns][pyarrow]" + ), + } + ) + conn = request.getfixturevalue(conn) + df.to_sql("test_arrow", conn, if_exists="replace", index=False) + + @pytest.mark.db @pytest.mark.parametrize("conn", all_connectable) @pytest.mark.parametrize("method", [None, "multi"]) From 91851e5bdfde19233132ab81a729e090ff82adc2 Mon Sep 17 00:00:00 2001 From: Patrick Hoefler Date: Fri, 24 Mar 2023 16:19:33 -0400 Subject: [PATCH 2/2] Simplify --- pandas/core/arrays/arrow/array.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/core/arrays/arrow/array.py b/pandas/core/arrays/arrow/array.py index b9508795e3c8e..6b722d800519c 100644 --- a/pandas/core/arrays/arrow/array.py +++ b/pandas/core/arrays/arrow/array.py @@ -2093,7 +2093,7 @@ def _dt_round( def _dt_to_pydatetime(self): data = self._pa_array.to_pylist() if self._dtype.pyarrow_dtype.unit == "ns": - data = [None if isna(ts) else ts.to_pydatetime(warn=False) for ts in data] + data = [None if ts is None else ts.to_pydatetime(warn=False) for ts in data] return np.array(data, dtype=object) def _dt_tz_localize(