Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

[Python] Cursor.fetch_polars() returns a struct Series instead of a DataFrame with polars 2

Open Beginner friendly
#4,915 1 comment 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
72/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
python
Domain
database

Research direction

_RowIterator.fetch_polars() in the Python driver manager is the entry point: it wraps polars.from_arrow(self.fetch_arrow()) in a typing.cast, which hides that polars 2 returns a polars.Series. Start by running the sqlite repro in the report and confirming the Series/struct output, then apply the unnest (or build a polars.DataFrame from the stream) and check the result is a DataFrame with columns a and b under both polars 1.x and 2.x, including an empty result.

Written by the indexing model from the issue text.

Description

Describe the bug

With polars 2.0, adbc_driver_manager.dbapi.Cursor.fetch_polars() returns a polars.Series with a single struct column instead of a polars.DataFrame.

_RowIterator.fetch_polars() calls polars.from_arrow(self.fetch_arrow()), which passes in an ArrowArrayStreamHandle. polars 2 now turns an Arrow C stream given to from_arrow into a struct Series. polars 1.x returned a DataFrame. The typing.cast(polars.DataFrame, ...) around the call hides this from type checkers.

Reproduce
import adbc_driver_sqlite.dbapi as d

with d.connect() as c, c.cursor() as cur:
    cur.execute("SELECT 1 AS a, 'x' AS b")
    r = cur.fetch_polars()
    print(type(r).__name__, r.dtype, r.shape)

Output with polars 2.0.0:

Series Struct({'a': Int64, 'b': String}) (1,)

Expected: a DataFrame with columns a and b. That is what polars 1.x returns.

Versions
  • adbc-driver-manager 1.12.0
  • polars 2.0.0
  • pyarrow 26.0.0
  • Python 3.12, Linux
Possible fix

One option is to unnest when polars hands back a Series:

result = polars.from_arrow(self.fetch_arrow())
if isinstance(result, polars.Series):
    result = result.struct.unnest()

Another is to build the frame with polars.DataFrame(...) from the stream. That needs checking against both polars 1.x and 2.x. We've applied the unnest workaround downstream in adbc-poolhouse 1.6.4, and it keeps the frame's schema, including for empty results.

Dominant language
C#
Stars
634
Forks
233
Avg merge
1d 8h
Merged PRs (30d)
91

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from apache/arrow-adbc

All issues in apache/arrow-adbc

Similar issues

More C# issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.