Architecture¶
Design target
Keep a stable DB-API surface while allowing backend implementation differences (pyodbc vs tbcli).
Layers¶
- Application code calls
pytibero.connect(...). pytibero.connection.Connectionselects a transport backend.pyodbcortbcliopens the real database connection.pytibero.cursor.Cursordelegates execute and fetch operations to the native cursor for thepyodbcbackend.pytibero.tbcliprovides a native Tibero client path for thetbclibackend.- Backend exceptions are mapped into package-owned DB-API exception classes.
Design choices¶
qmarkparameter style matchespyodbcand DB-API 2.0 expectations.- Package-owned exception classes keep the public API stable.
- Connection-string creation is isolated in
protocol.pyso backend behavior is testable. - Common native
pyodbcconnect kwargs are separated from ODBC string attributes. - The
tbclibackend uses Tibero's native client library throughctypes. - Cursor state tracks
rownumberlocally so DB-API iteration remains consistent. - Unit tests use a fake
pyodbcbackend; e2e tests validate the real driver path.
Runtime architecture map¶
mermaid
flowchart TD
A[Application SQL call] --> B[pytibero.Connection]
B --> C{backend}
C -->|pyodbc| D[pyodbc connection and cursor]
C -->|tbcli| E[ctypes tbcli driver]
D --> F[Native execution]
E --> F
F --> G[Result conversion and cursor state]
G --> H[Package exception mapping]
Connection construction sequence¶
```mermaid sequenceDiagram participant App as Application participant P as pytibero.connect participant C as Connection participant Pr as protocol.build_connection_string participant B as Backend
App->>P: connect(...)
P->>C: instantiate Connection
C->>C: split kwargs (native/options)
C->>C: load backend
alt pyodbc
C->>Pr: build_connection_string(config)
C->>B: pyodbc.connect(conn_str, **kwargs)
else tbcli
C->>B: tbcli.connect(config)
end
B-->>C: native connection
C-->>App: ready Connection object
```
Error portability
Application code should catch pytibero exceptions instead of backend-specific exception classes.