API surface
The top-level surface of informix_db and informix_db.aio. For full PEP 249 details, see the standard’s DB-API 2.0 spec.
Module-level
Section titled “Module-level”import informix_db
informix_db.connect(...) -> Connectioninformix_db.create_pool(...) -> Poolinformix_db.apilevel # "2.0"informix_db.threadsafety # 1informix_db.paramstyle # "numeric"from informix_db import aio
await aio.connect(...) -> aio.Connectionawait aio.create_pool(...) -> aio.Poolconnect()
Section titled “connect()”informix_db.connect( *, host: str, port: int = 9088, user: str, password: str, database: str | None, server: str, # DBSERVERNAME (not hostname) autocommit: bool = False, connect_timeout: float | None = None, read_timeout: float | None = None, keepalive: bool = False, client_locale: str = "en_US.8859-1", env: dict[str, str] | None = None, tls: bool | ssl.SSLContext = False,) -> ConnectionConnection
Section titled “Connection”| Method / property | Description |
|---|---|
cursor(scrollable=False) | Returns a new Cursor. Only one scrollable cursor may be open per connection; see below. |
commit() | Commits the current transaction. |
rollback() | Rolls back the current transaction. |
close() | Closes the connection. Idempotent. |
fast_path_call(routine, *args) | Direct UDF/SPL invocation, bypassing PREPARE/EXECUTE/FETCH. |
encoding | Resolved Python codec for client_locale. |
closed | True after close(). |
server_version | Server release, e.g. '…Version 12.10.FC6'. Costs one query on first access, then cached. |
server_version_internal | Raw login-response version string. Free. See note below. |
server_capabilities | Negotiated ServerCapabilities, or None if the reply couldn’t be decoded. |
Connection is also a context manager (with informix_db.connect(...) as conn:), which closes on exit.
There is no conn.transaction() helper and no conn.autocommit attribute. Earlier versions of this page listed both, and neither has ever existed. Set autocommit at connect time with connect(autocommit=True), and manage transactions with commit() / rollback():
conn = informix_db.connect(..., autocommit=False)try: cur = conn.cursor() cur.execute("UPDATE accounts SET balance = balance - ? WHERE id = ?", (100, 1)) cur.execute("UPDATE accounts SET balance = balance + ? WHERE id = ?", (100, 2)) conn.commit()except Exception: conn.rollback() raiseFetch methods return plain tuples by default. Pass row_factory to get rows that also answer to a column name and an attribute, the shape pyodbc and mssql-python provide:
conn = informix_db.connect(..., row_factory=informix_db.Row)cur = conn.cursor()cur.execute("SELECT tabid, tabname FROM systables")row = cur.fetchone()
row[0] # 1row["tabname"] # 'systables'row.tabname # 'systables'Set on the connection, so it applies to every cursor from it. A cursor can override it with cur.row_factory = informix_db.Row. Pools and the async API forward it unchanged.
Row subclasses tuple, so row == (1, "systables") is still true and anything treating rows as sequences keeps working. Slices return plain tuples, since a slice has no column map. row.keys() gives the column names and row._asdict() gives a dict.
Four behaviours worth knowing:
- Informix folds unquoted identifiers to lower case, so
SELECT Config_Keyis reachable asrow.config_key. The.lower()people add by hand when building this themselves is already a no-op. - Expression columns get server-generated names like
(count(*)), which cannot be Python attributes. Those are reachable by subscript only. - Duplicate column names resolve to the first occurrence, matching
pyodbc. Positional access still reaches both. - A column beats a method of the same name.
tupledefinescountandindex;Rowaddskeys,_asdictand_fields. A column with any of those names wins, because otherwise it would hand back a bound method instead of a value. The methods stay reachable astuple.count(row, x)andRow.keys(row).
Cursor
Section titled “Cursor”| Method / property | Description |
|---|---|
execute(sql, params=()) | Prepare + execute. Returns the cursor. |
executemany(sql, seq_of_params) | Pipelined batch execute. |
fetchone() | One row tuple, or None. |
fetchmany(size=arraysize) | List of row tuples. |
fetchall() | All remaining rows. |
scroll(value, mode="relative") | Scrollable cursor positioning. Needs cursor(scrollable=True). |
fetch_first() / fetch_last() | Jump to the first / last row. Scrollable cursors only. |
fetch_prior() / fetch_relative(n) / fetch_absolute(n) | Relative and absolute positioning. Scrollable cursors only. |
read_blob_column(sql, params) | Read a BLOB or CLOB column → bytes. |
write_blob_column(sql, data, params, clob=False) | Write a BLOB column; pass clob=True for CLOB. |
close() | Closes the cursor + releases server resources. |
closed | True after close(). |
description | Sequence of column descriptors per PEP 249. |
rowcount | Affected row count for DML; -1 for SELECT. |
rownumber | Current 0-indexed position, or None before the first row. |
arraysize | Default fetchmany() size. |
There are no read_clob_column / write_clob_column methods and no lastrowid attribute. Earlier versions of this page listed all three, and none have existed.
CLOBs go through the BLOB methods. read_blob_column returns bytes either way, so decode it yourself with the column’s encoding:
cur.write_blob_column( "INSERT INTO docs VALUES (?, BLOB_PLACEHOLDER)", "café résumé".encode("iso-8859-1"), (1,), clob=True,)raw = cur.read_blob_column("SELECT txt FROM docs WHERE id = ?", (1,))text = raw.decode("iso-8859-1")For a server-assigned SERIAL after an INSERT, ask the server. Informix exposes it through DBINFO:
cur.execute("INSERT INTO people (name) VALUES (?)", ("ada",))cur.execute("SELECT DBINFO('sqlca.sqlerrd1') FROM systables WHERE tabid = 1")new_id = cur.fetchone()[0]| Method | Description |
|---|---|
connection() | Context manager yielding a connection from the pool. |
close() | Closes all idle connections; waits for in-use to return. |
closed | True after close(). |
size | Current pool size. |
idle_count | Connections currently idle in the pool. |
aio.Pool is identical except its connection() is an async context manager and close() is async.
Exceptions
Section titled “Exceptions”Error├── Warning└── DatabaseError ├── InterfaceError ├── DataError ├── OperationalError │ └── PoolTimeout ├── IntegrityError ├── InternalError ├── ProgrammingError └── NotSupportedErrorSee Exceptions & error codes for the SQLCODE → exception mapping.