Send data to Deephaven from a Python client
This guide shows how to send data to Deephaven from an external Python application using pydeephaven and input tables. Input tables allow a client to add rows to a Deephaven table. Keyed input tables also let the client update and delete rows by key.
Note
If your data source can run directly on the Deephaven server, consider using server-side input tables or a table publisher or DynamicTableWriter instead. Server-side ingestion is generally more efficient because it avoids network overhead.
When to use client-side input tables
Use client-side input tables for:
- Managing reference data: Upload configuration, lookup tables, or other datasets that change infrequently.
- Tracking state: Maintain the latest status per entity (e.g., device status, order state, user preferences).
- Interactive editing: Allow users or external systems to add, update, or remove records.
- Forwarding external data: Relay data from message queues, APIs, or sensors running in separate processes.
Basic pattern
The basic pattern for sending data from a Python client is:
- Create an input table on the server using
Session.input_table. See Input table types to choose a keyed, append-only, or blink table. - Prepare data in your client application.
- Convert the data to a PyArrow table and upload it with
Session.import_table. - Add to the input table with
InputTable.add. For a keyed table,addinserts rows with new keys and replaces rows whose key already exists. - Close the uploaded table with
Table.closeto release server resources promptly.
Repeat steps 2-5 as needed.
Complete example
The following example tracks device status using a keyed input table. Each device has a unique ID, and updates replace the previous status for that device.
The example connects to a server that uses pre-shared key authentication. Replace YOUR_PASSWORD_HERE with your pre-shared key. See the Python client quickstart for other connection and authentication options.
This example sends one row per call for clarity. For higher volumes, send several rows in one upload, as shown in Batch uploads.
Input table types
The client supports three types of input tables. The snippets in this section run inside the session from the complete example and use the pa, session, and schema names it defines. The delete snippet also uses its keyed input_table.
Keyed
Key columns identify each row. Adding a row with an existing key replaces that row. You can also delete rows by key.
To delete rows from a keyed table, pass a table that contains every key column and no other columns to InputTable.delete. The server rejects a delete table that is missing a key column or has any other column. Keys that aren't in the table are ignored:
Append-only
Each call to add appends rows to the end of the table. Append-only tables have no key columns and don't support updates or deletes. Use this when you need to keep every row, such as a log or an event history.
Blink
Rows in a blink table are visible for only one update graph cycle, then disappear. Use this for event streams where you only need to process the latest batch.
Note
Blink input tables can't have key columns. input_table raises a ValueError if you pass both key_cols and blink_table=True.
Batch uploads
For better performance, batch multiple rows into a single upload. This snippet runs inside the session from the complete example and uses its imports (pa, datetime, and timezone) and its session, schema, and input_table names:
Memory management
Each call to import_table creates a temporary table on the server. The client releases it when the Python object is garbage-collected, but that timing is not deterministic.
Always call close on uploaded tables after adding data to the input table. This releases the temporary table on the server and marks the local object as closed. Use try/finally to ensure cleanup even if the call to add fails. The update_device and remove_device helpers in the complete example follow this pattern.