ODBC and PDO
ODBC is the strategically-preferred way to talk to DB2 from PHP, Python, Node, and basically anything that isn’t RPG. The driver ships with IBM i (the IBM i Access ODBC Driver), it works the same way from a PASE program on the partition as it does from Linux or Windows over TCP, and it’s the path IBM is consistently pointing toward for new development.
The full treatment — connection-string keywords, how to install unixODBC, all the PDO_ODBC and pyodbc and odbc.js examples — lives in the companion guide:
PHP / PDO / ODBC Toolkit Setup → Connecting to DB2
This chapter is the short version: enough to know what you’re installing, what it does, and where the long version is.
What ships with IBM i, and what comes from yum
The IBM i Access ODBC Driver is part of IBM i Access Client Solutions and is shipped on the partition as part of standard IBM i. You don’t yum install it; it’s already there at /QOpenSys/usr/lib/libcwbodbc.so (or wherever your release puts it).
What you do yum install is the driver manager — the layer that PASE programs use to find and load the IBM driver:
yum install -y unixODBC unixODBC-devel
This gives you /QOpenSys/pkgs/bin/odbcinst, the configuration files at /QOpenSys/etc/odbcinst.ini and /QOpenSys/etc/odbc.ini, and the libodbc.so that PHP, Python, Node, and others link against.
Plus, depending on the language:
# PHP
yum install -y php-pdo php-pdo-odbc
# Python
yum install -y python3-pyodbc
# Node — npm install in your project:
# npm install odbc
A canonical connection string
The form that works for almost everyone:
DRIVER={IBM i Access ODBC Driver};SYSTEM=localhost;UID=K3SAPP;PWD=...;NAM=1;DBQ=K3SDATA;CCSID=1208;UNICODESQL=1
The keywords that matter:
| Keyword | Value | Meaning |
|---|---|---|
DRIVER |
{IBM i Access ODBC Driver} |
The IBM-shipped driver. Note the curly braces and exact name. |
SYSTEM |
localhost (on-box) or hostname |
The IBM i to connect to. |
UID / PWD |
Your credentials | Use a service user (K3SAPP), never QSECOFR. |
NAM |
1 for SQL naming, 0 for system naming |
SQL naming (schema.table) is what most modern code expects. |
DBQ |
A library name | Default schema / library for unqualified references. |
CCSID |
1208 |
Connection-level character encoding negotiation. UTF-8. |
UNICODESQL |
1 |
Tells the driver that bound parameters and results are Unicode. |
The other 50+ ODBC keywords are documented (and sometimes critical for performance) in the toolkit guide. Read Connecting to DB2 when you need them.
ODBC in PHP, Python, Node — at a glance
PHP (PDO_ODBC):
$dsn = 'odbc:DRIVER={IBM i Access ODBC Driver};SYSTEM=localhost;UID=K3SAPP;PWD=...;NAM=1;DBQ=K3SDATA;CCSID=1208;UNICODESQL=1';
$pdo = new PDO($dsn);
$stmt = $pdo->query('SELECT custno, name FROM custmast FETCH FIRST 5 ROWS ONLY');
foreach ($stmt as $row) {
echo $row['CUSTNO'] . ' ' . $row['NAME'] . "\n";
}
Python (pyodbc):
import pyodbc
conn = pyodbc.connect(
'DRIVER={IBM i Access ODBC Driver};SYSTEM=localhost;UID=K3SAPP;PWD=...;'
'NAM=1;DBQ=K3SDATA;CCSID=1208;UNICODESQL=1'
)
for row in conn.cursor().execute('SELECT custno, name FROM custmast FETCH FIRST 5 ROWS ONLY'):
print(row.custno, row.name)
Node (odbc):
import odbc from 'odbc';
const conn = await odbc.connect(
'DRIVER={IBM i Access ODBC Driver};SYSTEM=localhost;UID=K3SAPP;PWD=...;' +
'NAM=1;DBQ=K3SDATA;CCSID=1208;UNICODESQL=1'
);
const result = await conn.query('SELECT custno, name FROM custmast FETCH FIRST 5 ROWS ONLY');
console.log(result);
All three call into the same IBM i Access driver, with the same connection string keywords, with the same CCSID and library-list semantics. That’s the ODBC promise.
Where next
For everything beyond the basics — the full keyword list, calling RPG from PHP through the toolkit on top of an existing PDO connection, performance tuning, prestart jobs, exit programs, custom subsystems for ODBC isolation — go to PHP / PDO / ODBC Toolkit Setup.
Otherwise, What belongs in IBM i OSS is next.