Getting started
A family of pure-native, high-performance ADBC drivers for SQL Server, PostgreSQL and Oracle. Each one speaks its database's wire protocol directly — the bytes the server itself expects, rather than a call into ODBC or a vendor client library.
Apache Arrow RecordBatches travel both ways: out of the database on the
read path, and back into it on the ingest path. Extraction and loading go
through the same driver, with no conversion to rows in between.
Which driver do I need?
| Your database | Driver | Load name | Also covers | Status |
|---|---|---|---|---|
| Microsoft SQL Server | ArrowTDS | arrowtds | Azure SQL, Microsoft Fabric | ✅ Published |
| PostgreSQL | ArrowFEBE | arrowfebe | PostgreSQL-compatible services | ✅ Published |
| Oracle | ArrowTTC | arrowttc | Oracle Cloud Autonomous Database, OCI IAM | ✅ Published |
| IBM Db2 | ArrowDRDA | arrowdrda | — | 🚧 Coming soon |
The driver binaries are published as public GitHub Releases and are free to download. They are licence-gated: a driver needs a valid Arpeio licence at runtime — there is no trial build. Contact sales@arpe.io for a licence.
The drivers
Install in one line
- Linux / macOS
- Windows (PowerShell)
curl -fsSL https://raw.githubusercontent.com/arpe-io/adbc-drivers/main/install.sh \
| sh -s -- arrowtds --license /path/to/your.lic
& ([scriptblock]::Create((irm https://raw.githubusercontent.com/arpe-io/adbc-drivers/main/install.ps1))) `
arrowtds -License C:\path\to\your.lic
Then load it by name from any ADBC client:
- Python
- C / C++
- C#
- Go
- Java
- R
- Rust
import adbc_driver_manager.dbapi as dbapi
with dbapi.connect(driver="arrowtds",
db_kwargs={"uri": "sqlserver://sa:<pw>@host:1433/?database=db&encrypt=true"}) as conn:
cur = conn.cursor()
cur.execute("SELECT * FROM dbo.orders")
table = cur.fetch_arrow_table() # ready as Arrow
#include <arrow-adbc/adbc.h>
// (error checks elided for brevity)
AdbcError e = {}; AdbcDatabase db = {}; AdbcConnection conn = {}; AdbcStatement st = {};
AdbcDatabaseNew(&db, &e);
AdbcDatabaseSetOption(&db, "driver", "arrowtds", &e);
AdbcDatabaseSetOption(&db, "uri", "sqlserver://sa:<pw>@host:1433/?database=db&encrypt=true", &e);
AdbcDatabaseInit(&db, &e);
AdbcConnectionNew(&conn, &e); AdbcConnectionInit(&conn, &db, &e);
AdbcStatementNew(&conn, &st, &e);
AdbcStatementSetSqlQuery(&st, "SELECT * FROM dbo.orders", &e);
ArrowArrayStream stream = {}; int64_t n = -1;
AdbcStatementExecuteQuery(&st, &stream, &n, &e); // consume `stream`
using Apache.Arrow.Adbc;
using Apache.Arrow.Adbc.DriverManager;
using var driver = AdbcDriverManager.FindLoadDriver("arrowtds", loadOptions: AdbcLoadFlags.Default);
using var database = driver.Open(new Dictionary<string, string> {
["uri"] = "sqlserver://sa:<pw>@host:1433/?database=db&encrypt=true" });
using var connection = database.Connect(null);
using var statement = connection.CreateStatement();
statement.SqlQuery = "SELECT * FROM dbo.orders";
using var stream = statement.ExecuteQuery().Stream!; // IArrowArrayStream
var drv drivermgr.Driver
db, _ := drv.NewDatabase(map[string]string{
"driver": "arrowtds",
adbc.OptionKeyURI: "sqlserver://sa:<pw>@host:1433/?database=db&encrypt=true",
})
conn, _ := db.Open(ctx)
stmt, _ := conn.NewStatement()
_ = stmt.SetSqlQuery("SELECT * FROM dbo.orders")
reader, _, _ := stmt.ExecuteQuery(ctx) // array.RecordReader
defer reader.Release()
Map<String, Object> params = new HashMap<>();
JniDriver.PARAM_DRIVER.set(params, "arrowtds");
AdbcDriver.PARAM_URI.set(params, "sqlserver://sa:<pw>@host:1433/?database=db&encrypt=true");
try (BufferAllocator a = new RootAllocator();
AdbcDatabase db = new JniDriver(a).open(params);
AdbcConnection conn = db.connect();
AdbcStatement st = conn.createStatement()) {
st.setSqlQuery("SELECT * FROM dbo.orders");
try (AdbcStatement.QueryResult r = st.executeQuery()) {
ArrowReader reader = r.getReader();
}
}
library(adbcdrivermanager)
db <- adbc_database_init(adbc_driver("arrowtds"),
uri = "sqlserver://sa:<pw>@host:1433/?database=db&encrypt=true")
con <- adbc_connection_init(db)
table <- read_adbc(con, "SELECT * FROM dbo.orders") |> arrow::as_arrow_table()
use adbc_core::{Connection, Database, Driver, Statement, LOAD_FLAG_DEFAULT};
use adbc_core::options::{AdbcVersion, OptionDatabase, OptionValue};
use adbc_driver_manager::ManagedDriver;
let mut driver = ManagedDriver::load_from_name("arrowtds", None, AdbcVersion::default(), LOAD_FLAG_DEFAULT, None)?;
let mut db = driver.new_database_with_opts([(OptionDatabase::Uri,
OptionValue::String("sqlserver://sa:<pw>@host:1433/?database=db&encrypt=true".into()))])?;
let mut conn = db.new_connection()?;
let mut stmt = conn.new_statement()?;
stmt.set_sql_query("SELECT * FROM dbo.orders")?;
let reader = stmt.execute()?; // impl RecordBatchReader
Swap arrowtds for arrowfebe or arrowttc. Full options, licence handling and
troubleshooting are on the Installation page.
Platforms: the drivers ship for Linux (x64) and Windows (x64). macOS binaries are staged but not yet published.