Migrate from IfxPy
If you have working IfxPy code, migration is mostly mechanical. Both drivers are PEP 249 with similar shapes; the differences are in connection construction, a few cursor extensions, and async support.
Connection construction
Section titled “Connection construction”# IfxPyimport IfxPyconn_str = ( "DATABASE=mydb;HOSTNAME=db.example.com;PORT=9088;" "PROTOCOL=onsoctcp;UID=informix;PWD=...;SERVICE=informix")conn = IfxPy.connect(conn_str, "", "")
# informix-driverimport informix_dbconn = informix_db.connect( host="db.example.com", port=9088, user="informix", password="...", database="mydb", server="informix",)The informix-driver keyword-argument form is closer to psycopg/asyncpg shapes. Connection strings aren’t supported (deliberately — they’re a security and parsing footgun).
The DB-API surface is the same
Section titled “The DB-API surface is the same”cursor(), execute(), fetchone(), fetchmany(), fetchall(), executemany(), description, rowcount, close() — all behave per PEP 249.
The exception hierarchy is identical: Error, Warning, InterfaceError, DatabaseError, DataError, OperationalError, IntegrityError, InternalError, ProgrammingError, NotSupportedError.
What IfxPy has that we don’t (yet)
Section titled “What IfxPy has that we don’t (yet)”- Named-parameter
callproc. We havefast_path_callfor direct UDF/SPL invocation but the API shape differs. - IBM-specific scrollable cursor extensions. We support PEP 249 scrollable cursors (
scroll(value, mode)) but not IfxPy’slast/prior/relativeshortcuts. cursor.set_chunk_size. We tune fetch behavior via the buffered reader; no per-cursor knob.
What we have that IfxPy doesn’t
Section titled “What we have that IfxPy doesn’t”- Async API (
from informix_db import aio) - Connection pool (
informix_db.create_pool/aio.create_pool) - Type-safe annotations —
informix-driverships withpy.typed - Python 3.12+ support
- Pipelined
executemany— 1.6× faster than IfxPy’s per-row implementation
Migrating incrementally
Section titled “Migrating incrementally”If your codebase has hundreds of IfxPy call sites, you can do a partial migration:
- Replace connection construction with
informix-driverat the application boundary. - Where you used
IfxPy.fetch_assoc(returns dict), wrap our cursor with a small adapter:def fetch_assoc(cur):row = cur.fetchone()if row is None:return Falsereturn dict(zip([c[0] for c in cur.description], row)) - For
IfxPy.exec_immediate, usecur.execute(sql)with no params. - For
IfxPy.bind_param, use the params arg ofexecute():cur.execute(sql, (a, b, c)).
Most application code can be migrated with sed-level transformations.