Skip to main content

ArpeOracle — Examples & recipes

Copy-paste snippets for the common tasks. All assume the driver is installed and loadable by name (driver="arpeoracle") — see Install. For the full option reference behind each db_kwargs, see Connection.


Connect and query to Arrow​

The same recipe in every ADBC client — the driver is loaded by name (arpeoracle) from the installed ADBC manifest, so only the language changes:

import adbc_driver_manager.dbapi as dbapi

with dbapi.connect(
driver="arpeoracle",
db_kwargs={"uri": "oracle://scott:tiger@localhost:1521/orclpdb1"},
) as conn, conn.cursor() as cur:
cur.execute("SELECT * FROM lineitem WHERE ROWNUM <= 10")
table = cur.fetch_arrow_table() # pyarrow.Table
print(table.schema)

Connect with discrete options​

Discrete options keep secrets out of a single string and override any uri. Set them where the uri went — the rest of each program is identical to the recipe above:

conn = dbapi.connect(driver="arpeoracle", db_kwargs={
"adbc.arpeoracle.server": "localhost",
"adbc.arpeoracle.port": "1521",
"adbc.arpeoracle.service_name": "orclpdb1",
"adbc.arpeoracle.username": "scott",
"adbc.arpeoracle.password": "tiger",
})

Straight to pandas / Polars​

The result is already Arrow, so these handoffs stay zero-copy — no row-by-row marshalling. pandas and Polars read straight from the ADBC connection:

Python
import adbc_driver_manager.dbapi as dbapi
import pandas as pd
import polars as pl

uri = "oracle://scott:tiger@localhost:1521/orclpdb1"

with dbapi.connect(driver="arpeoracle", db_kwargs={"uri": uri}) as conn:
# pandas — Arrow-backed dtypes, no Python-object columns
df = pd.read_sql(
"SELECT * FROM orders WHERE o_orderdate >= DATE '1996-01-01'",
conn, dtype_backend="pyarrow",
)

# Polars — reads the same ADBC result directly
pf = pl.read_database(
"SELECT * FROM orders WHERE o_orderdate >= DATE '1996-01-01'", conn
)

Connect and query from DuckDB​

DuckDB itself can be the ADBC client, via the third-party adbc_scanner community extension — it loads the arpeoracle driver and scans the result straight into DuckDB, in pure SQL:

-- DuckDB itself as the ADBC client, via the adbc_scanner community extension:
-- https://query.farm/products/extensions/adbc_scanner/
INSTALL adbc_scanner FROM community;
LOAD adbc_scanner;

-- Load the driver by name from the installed ADBC manifest.
SET VARIABLE conn = adbc_connect({
'driver': 'arpeoracle',
'uri': 'oracle://scott:tiger@localhost:1521/orclpdb1'
});

SELECT * FROM adbc_scan(getvariable('conn'), 'SELECT * FROM lineitem WHERE ROWNUM <= 10');

Prepared statements & parameter binding​

Oracle uses positional :1, :2 bind placeholders. In the compiled clients you bind an Arrow batch of parameters to the statement before executing:

with conn.cursor() as cur:
cur.execute("SELECT * FROM orders WHERE o_orderkey = :1", parameters=[42])
row = cur.fetch_arrow_table()

Array binding — bind a whole Arrow batch of parameters in one call (Python's executemany):

Python
with conn.cursor() as cur:
cur.executemany(
"INSERT INTO t(a, b) VALUES (:1, :2)",
seq_of_parameters=[(1, "x"), (2, "y"), (3, "z")],
)
conn.commit()

Bulk ingest an Arrow table​

adbc_ingest pipes an Arrow table straight in via an array-bound INSERT:

import pyarrow as pa

table = pa.table({
"id": pa.array([1, 2, 3], pa.int32()),
"name": pa.array(["a", "b", "c"], pa.string()),
})

with conn.cursor() as cur:
cur.adbc_ingest("my_table", table, mode="create") # create | append | replace | create_append
conn.commit()
note

Rust & C++ have no one-call adbc_ingest helper: set the standard statement options adbc.ingest.target_table / adbc.ingest.mode, Bind the Arrow batch, then execute_update (Rust) / AdbcStatementExecuteQuery (C++).

Ingest into a specific schema or a GLOBAL TEMPORARY table via the statement options adbc.ingest.target_db_schema / adbc.ingest.temporary (see Connection). Table and column names are used exactly as given (quoted), so my_table above is the case-sensitive "my_table" — see Data types.

Export a query to Parquet​

Python
import pyarrow.parquet as pq

with conn.cursor() as cur:
cur.execute("SELECT * FROM lineitem")
reader = cur.fetch_record_batch() # streaming RecordBatchReader
with pq.ParquetWriter("lineitem.parquet", reader.schema) as w:
for batch in reader:
w.write_batch(batch)

Streaming keeps memory flat regardless of result size. batch_size (rows per batch) is a memory knob, not a throughput knob — see Timeouts & performance.

Native Network Encryption​

Encrypt the whole session without TCPS — the way to connect a server configured SQLNET.ENCRYPTION_SERVER=REQUIRED:

Python
conn = dbapi.connect(driver="arpeoracle", db_kwargs={
"adbc.arpeoracle.server": "dbhost",
"adbc.arpeoracle.service_name": "orclpdb1",
"adbc.arpeoracle.username": "scott",
"adbc.arpeoracle.password": "tiger",
"adbc.arpeoracle.encryption": "required", # AES-256 payloads
"adbc.arpeoracle.data_integrity": "required", # SHA-256 checksum
})

TLS / Oracle Cloud ADB with a wallet​

Point wallet_location at an unzipped ADB wallet (mutual TLS):

Python
conn = dbapi.connect(driver="arpeoracle", db_kwargs={
"adbc.arpeoracle.server": "adb.<region>.oraclecloud.com",
"adbc.arpeoracle.port": "1522",
"adbc.arpeoracle.service_name": "<svc>_low.adb.oraclecloud.com",
"adbc.arpeoracle.username": "scott",
"adbc.arpeoracle.password": "tiger",
"adbc.arpeoracle.ssl_mode": "verify-full",
"adbc.arpeoracle.wallet_location": "/home/you/wallet",
"adbc.arpeoracle.wallet_password": "<wallet-pw>",
})

OCI IAM & OAuth2 / Entra ID token auth​

OCI IAM database token (oci iam db-token get writes the token directory); pair with the ADB wallet for mutual TLS:

Python
db_kwargs = {
"adbc.arpeoracle.server": "adb.<region>.oraclecloud.com",
"adbc.arpeoracle.port": "1522",
"adbc.arpeoracle.service_name": "<svc>_low.adb.oraclecloud.com",
"adbc.arpeoracle.auth_method": "token",
"adbc.arpeoracle.token_location": "/home/you/.oci/db-token",
"adbc.arpeoracle.ssl_mode": "verify-full",
"adbc.arpeoracle.wallet_location": "/home/you/wallet",
"adbc.arpeoracle.wallet_password": "<wallet-pw>",
}

OAuth2 / Microsoft Entra ID bearer token — setting the token auto-selects the method (no username; Oracle maps the token's upn claim to a global user):

Python
db_kwargs = {
"adbc.arpeoracle.server": "adb.<region>.oraclecloud.com",
"adbc.arpeoracle.port": "1522",
"adbc.arpeoracle.service_name": "<svc>_low.adb.oraclecloud.com",
"adbc.arpeoracle.access_token": "<entra-jwt>", # or token_file=<path>
# wallet options as above for ADB mutual TLS
}

See Authentication.

Loading by explicit path​

Load-by-name (above) uses the ADBC manifest the installer registers. When the driver is not installed system-wide, point the driver manager at the shared library instead — e.g. in C# via CAdbcDriverImporter.Load("libarpeoracle_adbc_driver-linux-x64.so", "AdbcDriverInit") (arpeoracle_adbc_driver-win-x64.dll on Windows). Alternatively, keep loading by name and point ADBC_DRIVER_PATH at the directory holding the arpeoracle.toml manifest. Everything after loading is identical.

See also​