Use case: quant analytics with pandas¶
Goal. A researcher pulls data out of the in-memory engine into pandas, for a notebook, a backtest, or an ad-hoc study, using standard Python database tools rather than the realtime client. No callbacks, no subscriptions: just query and get a DataFrame.
There are two ways in, both over the JDBC (SQL) protocol: the DB-API 2.0 driver and the
SQLAlchemy dialect. Use SQLAlchemy if you want pandas.read_sql or the ORM; use the DB-API for
plain cursor access.
Both need Python 3.14
The DB-API and SQLAlchemy layers both import the compiled native module, so both require Python
3.14. pyami.pyjdbc is native-free but plaintext-only (no TLS), and it is in the source
repository only: pip install pyami-3forge does not install it. See
Python client → Pure-Python JDBC.
SQLAlchemy + pandas (the common path)¶
The connection URL is ami+jdbc://<user>:<password>@<host>:<port> with optional query parameters:
Note the expression syntax in WHERE: equality is == and string literals use double quotes. The
dialect also supports reflection (get_table_names, get_columns) so tools that introspect the schema
work.
DB-API 2.0 (plain cursor access)¶
connect(host, port=3280, username, password, timeout_ms=60000, limit=10000, use_ssl=True, …). The
paramstyle is named:
Limits to plan around¶
Results are capped, raise the limit for a full pull
The default row limit is 10 000 (DB-API limit=, or ?limit= on the SQLAlchemy URL). A study
over a larger table must raise it or page the query, or it silently gets only the first 10 000 rows.
The default query timeout is 60 000 ms on the DB-API / SQLAlchemy path.
No transactions
The DB-API driver has no transactions, commit and rollback are no-ops. This is a read-and-load
path, not a unit-of-work path. For high-volume writes, use the native client's bulk insert (see
Python client → Bulk insert).
Date/time columns carry epoch integers with no time zone
A temporal value comes back as a raw epoch integer (seconds / milliseconds / nanoseconds) with no
time-zone attached, convert it in your client and agree the zone out of band. The pure-Python
pyami.pyjdbc layer cannot decode temporal columns at all; if you must use it, select the instant
as a Long epoch or a String. See Concepts → The type system.
Connecting securely¶
On a mutual-TLS server, the DB-API path takes the certificate arguments directly, this is the verified route for a secured read:
For SQLAlchemy, forward the same arguments to the underlying DB-API connect via connect_args:
The plain ami+jdbc://… URL forms shown earlier assume a listener with no keystore (plain TCP). See
Configuration → Connecting to a secured server.
What this shows¶
- Standard tools work: the SQLAlchemy dialect and DB-API driver mean pandas, notebooks, and ORM code talk to 3forge Enterprise with no bespoke client.
- This is a read/analytics path: query and load; for streaming use the Center subscription, for writes use bulk insert.