diff --git a/requirements.txt b/requirements.txt index ba886f90..b42741b8 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,6 +5,7 @@ coverage unittest-xml-reporting psutil pyarrow +polars # Runtime dependencies needed for tests azure-identity diff --git a/tests/test_024_bulkcopy_arrow.py b/tests/test_024_bulkcopy_arrow.py index a52ead3e..a840853b 100644 --- a/tests/test_024_bulkcopy_arrow.py +++ b/tests/test_024_bulkcopy_arrow.py @@ -554,6 +554,30 @@ def test_c_stream_producer(self, cursor): assert result["rows_copied"] == 2 cursor.execute(f"DROP TABLE {t}") + def test_polars_string_view_c_stream(self, cursor): + """GH-708: Polars string columns export as Utf8View and bulk-copy directly.""" + pl = pytest.importorskip("polars") + t = "mssql_python_arrow_polars_string_view" + _make_table(cursor, t, "id INT NOT NULL, name VARCHAR(50) NULL") + frame = pl.DataFrame( + { + "id": pl.Series([1, 2, 3], dtype=pl.Int32), + "name": ["alpha", None, "gamma"], + } + ) + schema = pa.RecordBatchReader.from_stream(frame).schema + assert schema.field("name").type == pa.string_view() + + result = cursor.bulkcopy_arrow(t, frame) + assert result["rows_copied"] == 3 + cursor.execute(f"SELECT id, name FROM {t} ORDER BY id") + assert [tuple(row) for row in cursor.fetchall()] == [ + (1, "alpha"), + (2, None), + (3, "gamma"), + ] + cursor.execute(f"DROP TABLE {t}") + def test_c_array_producer_single_batch(self, cursor): t = "mssql_python_arrow_carray" _make_table(cursor, t, "id INT NOT NULL, name NVARCHAR(20) NULL")