Skip to main content

ArpeNetezza — Examples & recipes

Copy-paste snippets for the common tasks. All assume the driver is loadable by name (driver="arpenz"), through an arpenz.toml manifest on the ADBC driver manager's search path. Otherwise, use Loading by explicit path. 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 (arpenz), so only the language changes:

import adbc_driver_manager.dbapi as dbapi

with dbapi.connect(
driver="arpenz",
db_kwargs={"uri": "netezza://admin:<pw>@nzhost:5480/SYSTEM"},
) as conn, conn.cursor() as cur:
cur.execute("SELECT * FROM lineitem LIMIT 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="arpenz", db_kwargs={
"adbc.arpenz.server": "nzhost",
"adbc.arpenz.port": "5480",
"adbc.arpenz.database": "SYSTEM",
"adbc.arpenz.username": "admin",
"adbc.arpenz.password": "<pw>",
})

Straight to pandas / Polars​

The result is already Arrow, so these handoffs need no row-by-row conversion. 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 = "netezza://admin:<pw>@nzhost:5480/SYSTEM"

with dbapi.connect(driver="arpenz", 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
)

Parameter binding​

Use ? placeholders. Netezza has no server-side prepared statements, so the driver renders each bound value into the SQL text as an escaped literal, and runs the statement once per parameter row. See Bound parameters.

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

Several parameter rows in one call (Python's executemany) run the statement once per row:

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

For more than a handful of rows, use bulk ingest instead.

Bulk ingest an Arrow table​

adbc_ingest streams an Arrow table into Netezza through the external-table load, falling back to batched INSERT when needed (see Data types → Write path). The data must arrive as a stream (BindStream), and adbc.ingest.mode must be set:

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

With autocommit on (the default), each ingest is one transaction. Choose the load path with adbc.arpenz.ingest_method (auto, external, insert):

Python
conn = dbapi.connect(driver="arpenz", db_kwargs={
"uri": "netezza://admin:<pw>@nzhost:5480/SYSTEM",
"adbc.arpenz.ingest_method": "external", # fail instead of falling back to INSERT
})

Ingest into a specific schema or a 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".

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; buffer_size sets the rows per batch (default 32000). INTERVAL columns stay Parquet-writable as long as interval_type is left at its text default.

TLS​

Verify the server (verify-full) against a CA file, which IBM Cloud NPS needs (see Authentication):

Python
conn = dbapi.connect(driver="arpenz", db_kwargs={
"adbc.arpenz.server": "nz-<instance-guid>.<region>.data-warehouse.cloud.ibm.com",
"adbc.arpenz.database": "SYSTEM",
"adbc.arpenz.username": "admin",
"adbc.arpenz.password": "<pw>",
"adbc.arpenz.sslmode": "verify-full",
"adbc.arpenz.ssl_root_cert": "/path/to/ibm_nps_ca.pem",
})

An NPS 7 server, which only offers TLS 1.0 / 1.1, with encryption required. This combination is not yet validated against a live NPS 7 (see Authentication → NPS 7); if the handshake fails, use sslmode=disable on a trusted network:

Python
conn = dbapi.connect(driver="arpenz", db_kwargs={
"uri": "netezza://admin:<pw>@nz7host:5480/SYSTEM?sslmode=require",
"adbc.arpenz.tls_min_version": "1.0",
})

Loading by explicit path​

Load-by-name uses an arpenz.toml ADBC driver manifest on the driver manager's search path (point ADBC_DRIVER_PATH at its directory if needed). Without one, pass the shared library's path as the driver:

Python
conn = dbapi.connect(
driver="/opt/arpeio/libarpenz_adbc_driver-linux-x64.so", # Windows: r"C:\arpeio\arpenz_adbc_driver-win-x64.dll"
db_kwargs={"uri": "netezza://admin:<pw>@nzhost:5480/SYSTEM"},
)

In C# use CAdbcDriverImporter.Load("libarpenz_adbc_driver-linux-x64.so", "AdbcDriverInit"). Everything after loading is identical. When loading by path, put the licence file arpeio_adbc.lic next to the library, or supply the licence another way (see Licensing).

See also​