22 - numpy Bulk I/O Workflow¶
Every path in this example crosses the Python/Java boundary once per batch instead of once per value. Per-row FFI calls cap document ingest around 30k rows/s regardless of engine speed; the batched paths below reach hundreds of thousands of rows or points per second on the same machine.
It covers:
- bulk document ingest with
Database.insert_many()(rows serialized as one JSON batch, looped Java-side), in both transactional-batch and async parallel-writer modes. Each bucket is owned by one async writer, so the parallel mode runs on a type created with as many buckets as the executor's parallel level (async_executor().get_parallel_level(), default cores - 1; ArcadeData/arcadedb#8478).commit_everydoes not apply to that mode, and it raisesArcadeDBErrorafter the load if the writers rejected any record. Seeinsert_many - time-series ingest straight from numpy arrays via
AsyncExecutor.append_samples()- timestamps and numeric field columns cross the boundary as one buffer copy per column - time-bucketed aggregation over the native
TIMESERIEStype (ts.timeBucketwith a boundedWHERE ts BETWEENrange) - columnar export with
to_columns(): scalar columns come back as 1-D numpy arrays and embedding columns as one contiguous 2-Dfloat32array, ready for scikit-learn or faiss without per-row conversion - the same export through
to_arrow(), which reads the same bridge buffer but keeps the validity bitmap. A nullableINTEGERstaysint64instead of widening tofloat64with NaN holes, and a nullableBOOLEANstaysboolinstead of degrading to a Python list. That section needs pyarrow (pip install 'arcadedb-embedded[arrow]') and skips itself without it.
Run¶
From bindings/python/examples:
python 22_numpy_bulk_io.py
# reduced scale:
python 22_numpy_bulk_io.py --rows 50000 --points 100000 --vectors 5000
The database is created under ./my_test_databases/numpy_bulk_io (--db-path).