[MongoDB] Handle out-of-range BSON datetimes to prevent sync failures#4148
Open
Jan-Kazlouski-elastic wants to merge 3 commits into
Open
[MongoDB] Handle out-of-range BSON datetimes to prevent sync failures#4148Jan-Kazlouski-elastic wants to merge 3 commits into
Jan-Kazlouski-elastic wants to merge 3 commits into
Conversation
Documents containing dates outside the Python datetime range (years 1-9999) caused pymongo to raise InvalidBSON during decode, aborting the entire sync. Configure the client with DATETIME_AUTO so such values are returned as DatetimeMS, and serialize them as raw milliseconds since epoch. Relates to elastic/sdh-search#1924 Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Switch datetime_conversion from DATETIME_AUTO to DATETIME_CLAMP so out-of-range BSON dates are clamped to datetime.min/max and stay valid dates. This avoids the mixed date/long Elasticsearch mapping conflict that DATETIME_AUTO could cause, and removes the now-unneeded DatetimeMS serialization branch. Co-authored-by: Cursor <cursoragent@cursor.com>
Member
|
Just checking - how is it related to the support case? |
Contributor
Author
Not directly. Looking into the support case just triggered agent to look into related issues and this was found. I decided it would be a good easy drive by fix. |
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.
Summary
Documents containing dates outside the Python
datetimerange (years 1–9999) cause pymongo to raiseInvalidBSONwhile decoding, which aborts the entire MongoDB sync:This PR configures the MongoDB client with
DatetimeConversion.DATETIME_CLAMP, so out-of-range values are clamped todatetime.min/datetime.maxand remain valid dates. They then serialize to normal ISO date strings, exactly like in-range dates.Why DATETIME_CLAMP (and not DATETIME_AUTO)
The earlier (closed) PR #3476 used
DATETIME_AUTO, which keeps in-range values as dates but converts out-of-range values tolong(epoch millis). That makes a single field hold mixed types (ISO string vs. long). Because Elasticsearch infers a field's type from the first document it sees, a later document of the other type is then rejected — turning the hard crash into an order-dependent ingestion failure.DATETIME_CLAMPavoids this entirely: every date serializes as a date string, so there is one consistent mapping, no crash, and no breaking change for existing users. The trade-off is that extreme dates lose their exact value (clamped to the datetime bounds) — an acceptable outcome for what are almost always sentinel/garbage dates.Context
This revives and supersedes the work from the earlier (closed) PR #3476, which was never merged and predates the connector package refactor (it targeted the old single-file
connectors/sources/mongo.py). This PR ports the fix to the currentconnectors/sources/mongo/package layout, switches the strategy to clamping, and adds unit test coverage.Changes
get_client(): setdatetime_conversion=DatetimeConversion.DATETIME_CLAMP.serialize(): no special date handling needed — clamped values are ordinarydatetimeobjects and go through the existingdatetime -> isoformat()branch.DATETIME_CLAMP, and an end-to-end test that encodes an out-of-range BSON date, decodes it with the client codec, and confirms it becomes a clampeddatetimeserialized as an ISO string (never aDatetimeMSor a number).Test plan
make clean install autoformat lint test PYTHON=python3.11(all MongoDB tests pass; unrelated pre-existing flaky failures only)Release Note
MongoDB connector: set default
datetime_conversiontoDatetimeConversion.DATETIME_CLAMPso out-of-rangedatetimevalues from MongoDB are clamped to valid dates instead of aborting the sync. See https://www.mongodb.com/docs/languages/python/pymongo-driver/current/data-formats/dates-and-times/#handling-out-of-range-datetimes for additional information.