Skip to content

Pandas4Warning emitted when converting a query result or table with a timestamp-with-timezone (or date with date_as_object=True) column to a Pandas v3.1 dataframe #708

Closed

Description

@edgarrmondragon

What happens?

The following warning is emitted when converting to a pandas v3.1 dataframe:

Pandas4Warning: The inplace keyword in DataFrame.drop is deprecated and will be removed in a future version (PDEP-8).
See https://pandas.pydata.org/docs/dev/whatsnew/v3.1.0.html#deprecation-inplace for more details.

The actual deprecation docs are at:

https://pandas.pydata.org/docs/whatsnew/v3.1.0.html#deprecated-inplace-keyword-for-various-methods

FWIW, the only place I was able to find where .drop() is called is

static void ReplaceDFColumn(PandasDataFrame &df, const char *col_name, idx_t idx, const nb::handle &new_value) {
df.attr("drop")("columns"_a = col_name, "inplace"_a = true);
df.attr("insert")(idx, col_name, new_value, "allow_duplicates"_a = false);
}

And the logic that's calling this for timestamptz columns seems to be

if (types[i] == LogicalType::TIMESTAMP_TZ) {
// first localize to UTC then convert to timezone_config
auto utc_local = df[names[i].c_str()].attr("dt").attr("tz_localize")("UTC");
auto new_value = utc_local.attr("dt").attr("tz_convert")(GetClientProperties().time_zone);
// We need to create the column anew because the exact dt changed to a new timezone
ReplaceDFColumn(df, names[i].c_str(), i, new_value);
} else if (date_as_object && types[i] == LogicalType::DATE) {
nb::object new_value = df[names[i].c_str()].attr("dt").attr("date");
ReplaceDFColumn(df, names[i].c_str(), i, new_value);
}

To Reproduce

# /// script
# requires-python = "==3.15.*"
# dependencies = ["duckdb==2.0.0", "pandas==3.1.0"]
# ///
import warnings

import duckdb

warnings.simplefilter("error")  # same effect as `python -W error`

# Any timezone-aware timestamp column triggers it; a plain `select 1 a` does not.
duckdb.sql("select timestamptz '2020-01-01 00:00:00+00' as tz").df()

OS:

OSX

DuckDB Package Version:

2.0.0

Python Version:

3.15

Full Name:

Edgar Ramírez Mondragón

Affiliation:

Meltano

What is the latest build you tested with? If possible, we recommend testing with the latest nightly build.

I have tested with a stable release

Did you include all relevant data sets for reproducing the issue?

Yes

Did you include all code required to reproduce the issue?

  • Yes, I have

Did you include all relevant configuration to reproduce the issue?

  • Yes, I have

Activity

  1. mohamd764 commented on Oct 23, 2026

    @mohamd764

    I could reproduce this on Linux with Python 3.13.5, duckdb 2.0.0 and pandas 3.1.0. With pandas 3.0.6 and the same duckdb wheel, there is no warning, so it starts with the 3.1 inplace deprecation (PDEP-8).

    import warnings, duckdb
    warnings.simplefilter("error")
    duckdb.sql("select timestamptz '2020-01-01 00:00:00+00' as tz").df()
    # pandas.errors.Pandas4Warning: The inplace keyword in DataFrame.drop is deprecated ...

    Two things that might help scope the fix:

    • It's not only TIMESTAMPTZ. ConvertDateTimeTypes goes through the same ReplaceDFColumn helper for the date_as_object path, so duckdb.sql("select date '2020-01-01' d").df(date_as_object=True) raises the same warning under simplefilter("error"). .fetchdf() and .fetch_df_chunk() hit it too.
    • The warning gets attributed to duckdb/_relation.py and not to the caller's line. A filterwarnings entry keyed on the user's module won't match it, which makes this awkward to silence in test suites.

    ReplaceDFColumn (src/pyresult.cpp, still at L304 on main 4154efc) only needs to drop the column in place. del df[col_name] does that without the deprecated keyword. I checked this in plain pandas 3.1.0 on a frame shaped like the one this function sees, a tz-naive column re-localized to UTC and converted. del df["tz"] followed by the existing df.insert(idx, "tz", new_value, allow_duplicates=False) gives a frame that passes pd.testing.assert_frame_equal against the current drop(inplace=True) + insert result: same column order and the same datetime64[us, <tz>] dtype, with no warning. Plain df[col_name] = new_value also gave an identical frame, since it replaces the column at its existing position. In C++ that would be something like df.attr("__delitem__")(col_name); in place of the drop(...) call. I haven't built the extension with that change, so I've only verified it at the pandas level.

  2. changed the title [-]`Pandas4Warning` emitted when converting a query result or table with a timestamp-with-timezone to a pandas dataframe[/-] [+]`Pandas4Warning` emitted when converting a query result or table with a timestamp-with-timezone to a Pandas v3.1+ dataframe[/+] on Oct 23, 2026
  3. changed the title [-]`Pandas4Warning` emitted when converting a query result or table with a timestamp-with-timezone to a Pandas v3.1+ dataframe[/-] [+]`Pandas4Warning` emitted when converting a query result or table with a timestamp-with-timezone to a Pandas v3.1 dataframe[/+] on Oct 23, 2026
  4. changed the title [-]`Pandas4Warning` emitted when converting a query result or table with a timestamp-with-timezone to a Pandas v3.1 dataframe[/-] [+]`Pandas4Warning` emitted when converting a query result or table with a timestamp-with-timezone or date column to a Pandas v3.1 dataframe[/+] on Oct 23, 2026
  5. changed the title [-]`Pandas4Warning` emitted when converting a query result or table with a timestamp-with-timezone or date column to a Pandas v3.1 dataframe[/-] [+]`Pandas4Warning` emitted when converting a query result or table with a timestamp-with-timezone (or date with `date_as_object=True`) column to a Pandas v3.1 dataframe[/+] on Oct 23, 2026
  6. edgarrmondragon commented on Oct 23, 2026

    @edgarrmondragon
    Author

    The warning gets attributed to duckdb/_relation.py and not to the caller's line. A filterwarnings entry keyed on the user's module won't match it, which makes this awkward to silence in test suites.

    Yeah, I don't think it's easy to surface warnings coming from extension-level code.

    It's not only TIMESTAMPTZ

    Yeah, the cpp code I linked to already reflected that, but I've updated the MRE and the title to include that.

  7. edgarrmondragon commented on Oct 23, 2026

    @edgarrmondragon
    Author

    a897283 fixed this, but I'll let the maintainer close this issue when they deem it appropriate

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions