SQL Server into Apache Arrow with ADBC
SQL Server 2022, read and written through adbcBridge — the ADBC driver that loads the database's ODBC driver — verified on Linux, macOS arm64 and Windows x64. Everything below is the compatibility matrix's record for this row.
Status
PASS
PASS (SQL Server 2022)
PASS (SQL Server 2022 16.00.4265, mcr.microsoft.com/mssql/server:2022 container; msodbcsql 18.6.2.1)
Driver and connection string
- ODBC driver
- msodbcsql 18
- Wire
- native ODBC
- adbcBridge
- 0.1.1 (release)
The connection string the matrix used, as the connection strings reference records it (SQL Server); {drv} is the driver library or its name from odbcinst.ini, and the host, port and credentials are the test server's.
Driver={drv};Server=127.0.0.1,14331;Database=master;Uid=sa;Pwd=Adbc!Bridge2026;TrustServerCertificate=yes;
Python
import adbcbridge
# {drv}: the ODBC driver library (path), or its name from odbcinst.ini
conn = adbcbridge.connect(uri="Driver={drv};Server=127.0.0.1,14331;Database=master;Uid=sa;Pwd=Adbc!Bridge2026;TrustServerCertificate=yes;")
with conn.cursor() as cur:
cur.execute("SELECT * FROM my_table")
table = cur.fetch_arrow_table() # pyarrow.Table
Polars and pandas
import polars as pl, pandas as pd
df = pl.read_database("SELECT * FROM my_table", connection=conn) # Polars, Arrow-native
pdf = pd.read_sql("SELECT * FROM my_table", conn) # pandas 2.2+, ADBC connection
pip install adbcbridge brings the driver library; the SQL Server ODBC driver is installed the way its vendor documents, then named in Driver=. Rust, Go, C# and Java use the same connection string through their ADBC driver managers — see the docs.
What the matrix recorded
incl.
What this stack needed
NVARCHAR(MAX)via chunkedSQLGetData— the driver describes it asSQL_WVARCHARwith column size 0 and reportsSQL_GETDATA_EXTENSIONS=SQL_GD_BLOCKonly, so a value truncated in a *bound* column cannot be re-read (07009 on every route) and the wide column is left unbound; ingest DDL spells an Arrow stringNVARCHAR(MAX), not the deprecatedTEXTthe driver'sSQLGetTypeInfo(SQL_LONGVARCHAR)names (SQL Server will not sort, group or even compare it,IS NULLandLIKEexcepted).- A rowset above 1 makes every
SELECTreturn01S02 Cursor type changed, benign