fix: preserve Decimal precision during serialization - #22
Open
rtmalikian wants to merge 1 commit into
Open
Conversation
The Decimal serializer previously converted all values to float,
causing Decimal('19') to serialize as 19.0 in JSON output. Per the
FHIR spec, decimal precision is semantically significant: 19, 19.0,
and 19.00 are clinically distinct values.
Fix: check the Decimal's internal exponent to determine serialization
format. Values with exponent >= 0 (no fractional digits specified)
serialize as int; others serialize as float. This preserves the
original precision through model_dump() and model_dump_json().
Also removed the return_schema constraint from the serializer since
it now returns int/float instead of Decimal.
Closes nazrulworld/fhir.resources#203
Owner
|
Hi @rtmalikian thanks a lot for your PR. |
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
Fixes Decimal precision loss during serialization. Previously,
Decimal('19')was serialized as19.0in bothmodel_dump()andmodel_dump_json()because the serializer unconditionally converted tofloat.Per the FHIR spec, decimal precision is semantically significant:
19,19.0, and19.00are clinically distinct values representing different measurement precisions.Root Cause
The
_serializefunction inDecimal.__get_pydantic_core_schema__usedreturn float(value), which convertsDecimal('19')to19.0— losing the precision information.Fix
Check the Decimal's internal
exponent(fromas_tuple()) to determine the correct serialization format:exponent >= 0(e.g.,Decimal('19'),Decimal('0')): serialize asint→ JSON renders19,0exponent < 0(e.g.,Decimal('19.0'),Decimal('19.5')): serialize asfloat→ JSON renders19.0,19.5This preserves the original precision through both
model_dump()andmodel_dump_json().Also removed the
return_schema=core_schema.decimal_schema()constraint from the serializer, since it now returnsint/floatinstead ofDecimal.Test Results
Verification
Closes nazrulworld/fhir.resources#203
About the Author: Raphael Malikian — Clinical AI Solutions Architect. I specialise in building and fixing AI/ML systems for healthcare, including vector databases, RAG pipelines, and clinical NLP. If you need help with your project or think I can add value to your organisation, feel free to reach out — I'd love to connect.
📧 rtmalikian@gmail.com
🔗 GitHub: https://github.com/rtmalikian
🔗 LinkedIn: http://www.linkedin.com/in/raphael-t-malikian-mbbs-bsc-hons-71075436a
Disclosure: This code was developed with assistance from mimo-v2.5-pro (Xiaomi) via Hermes Agent (Nous Research). All changes were reviewed, tested against the actual codebase, and verified for correctness.