Repository navigation
insert_many: date-times, Decimals, bytes, numpy scalars and pandas NA stay on the bulk path; an uncarriable value moves its own row, not the chunk - #50
Closed
tae898 wants to merge 2 commits into
Conversation
…o longer moves its 10,000-row chunk to the per-row path
A datetime, date, Decimal, bytes, numpy scalar, pandas NA or NaT sitting directly in a row now crosses inside the JSON text as a tagged value ({"\u0001": [kind, payload]}) that DocumentBatcher.fill decodes to the objects the per-row path builds (LocalDateTime, LocalDate, BigDecimal, byte[]). A value the text still cannot carry (NaN, Infinity, an integer beyond 64 bits, a date-time inside a list or map, a lone surrogate, a datetime.time) sends only its own row down the per-row path, in order, and the rows around it stay on the bulk path. The parallel mode does the same. Port of humemai/arcadedb-embedded-python#528.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Collaborator
Author
|
Moved to #82: the personal fork was retired, so the branch now lives on ArcadeData/arcadedb-python as |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This is the port of humemai/arcadedb-embedded-python#528 (package
arcadedb, no "embedded" names).insert_manysends each 10,000-row chunk to the engine as one JSON text. Until nowjson.dumpsraised on adatetime,date,Decimal,bytes, a numpy scalar or a pandasNA/NaT, and one such value anywhere in a chunk sent the whole chunk down the per-row path (new_document+setper property +save, about 10 JPype crossings per row). Real tables nearly always carry a timestamp or a decimal, so most loads never reached the bulk path (backlog rows N-04, J-04, J-05).What changes
{"\u0001": [kind, payload]}:T(datetime, as the UTC wall clock the per-row path stores),D(date),n(Decimal),b(bytes, base64).DocumentBatcher.filldecodes the tag to the objectconvert_python_to_javabuilds for the per-row path (LocalDateTime,LocalDate,BigDecimal,byte[]). Numpy scalars cross as plain numbers (np.bool_as a bool),pandas.NA/NaT/np.datetime64('NaT')as null,pandas.Timestampandnp.datetime64as a naivedatetime(microseconds, as the per-row path keeps them).datetime/Decimalinside a list or dict, a non-str dict key, a lone surrogate, adatetime.time, a numpylongdoubleortimedelta64, a non-finiteDecimal. Runs of carriable rows still go in bulk, and every row is inserted in the order given. Inparallel=Truethe uncarriable rows are written synchronously after the writers drain (the writers never kept order).json_bulk_dumps(used byGraphBatch) is unchanged; onlyinsert_manyuses the newjson_bulk_dumps_tagged, because onlyDocumentBatcher.filldecodes the tags. A user dict keyed by the tag marker is refused by the bulk path, so it stays a map.insert_dataframe/insert_arrow/insert_columnswith a null in a numeric column (the other half of J-05) still builds anObject[]element by element. That is a separate Java change (a validity mask), so it gets its own PR.Stored values
tests/test_insert_many_mixed_values.pywrites the same rows through the per-row path and throughinsert_many, into a declared type (DATETIME, DATE, DECIMAL, BINARY, LONG, INTEGER, DOUBLE, FLOAT, BOOLEAN properties) and a schemaless one, and compares the stored value and its Python type for 17 value kinds (naive and UTC+9 datetime, date, Decimal with and without exponent, bytes, bytearray, np.int64/int8/uint32/float64/float32/bool_, None). It countsDatabase.new_documentcalls to prove which path ran, and also coverspandas.Timestamp(naive with nanoseconds, aware),pandas.NA/NaTandnp.datetime64(the per-row path raises for these; the bulk path stores null / a naive datetime), a 10,000-row chunk with one datetime, an uncarriable row in the middle of 1,000 (exactly onenew_documentcall, stored rows equal the per-row path's), insertion order around per-row runs,commit_everyacross chunks, rollback on a failing row,parallel=True, and the tag lookalike. The suite failed 15 of 20 tests before the change.Untimed 1M-row figure
One run each (not through
ab.py, so no claim), fresh process, 1,000,000 rows of six properties with a Pythondatetimeper row, row building inside the timed call, JVM-Xmx4g, throughquiet_build:insert_manytook 31.2 s before (1,000,000new_documentcalls, the whole load on the per-row path) and 7.4 s after (0new_documentcalls). The same rows without thetscolumn take 4.1 s, so the datetime itself now costs about 3.3 s per million rows (JSON text plusLocalDateTime.parse) instead of 27 s. Measured on the humemai fork (humemai/arcadedb-embedded-python#528) with the same change.Local checks
tests/test_insert_many_mixed_values.py20 passed, plustest_bulk_insert.py,test_bulk_json_paths.py,test_float_vector_bulk.py,test_numpy_support.py,test_conversion_fixes.py,test_graph_batch.py,test_insert_columns.py,test_async_executor.py,test_core.py,test_bridge_fixes.py,test_type_conversion.py,test_docs_examples.py,test_check_test_skips.py(all pass) against the engine jars and JRE of the humemai main CI wheel with this branch's Python files and the bridge classes compiled into a copy of the bridge jar (171 passed for the five suites listed first)Docs changed in this PR: the
insert_manydocstring (what is carried, what still goes per row). This repository keeps its API reference in Antora modules that do not describe theinsert_manyfallback, so there is no other page to update.🤖 Generated with Claude Code