Fix: emit BigQuery NUMERIC / BIGNUMERIC as JSON numbers, not strings#10
Conversation
BQ `NUMERIC` / `BIGNUMERIC` come back as `decimal.Decimal`; the existing `_json_default` (and `_orjson_default`) stringified them, so clients saw `"price": "5336.69"` instead of `"price": 5336.69`. Integers and FLOAT64 were already correct — only the Decimal path was off. Convert Decimal -> float in both default callbacks so orjson emits a JSON number. Trade-off documented inline: values past ~15 significant digits round to nearest IEEE-754 double, and callers needing full precision should `CAST(... AS STRING)` in `datastore_search_sql`. Tests updated to pin the JSON-number contract explicitly via `isinstance(..., float)` so a regression to strings fails loudly.
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (3)
📝 WalkthroughWalkthroughThe PR updates ChangesDecimal JSON Serialization
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes Possibly related PRs
Poem
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Summary
NUMERIC/BIGNUMERICcolumns come back asdecimal.Decimal. The_json_defaultand_orjson_defaultcallbacks were stringifying them, so a response carryingprice = Decimal("5336.69")was emitted as"price": "5336.69"rather than"price": 5336.69. Clients had to special-case parsing those numeric fields.float(obj)so orjson emits a JSON number. Comment explains the trade-off (values past ~15 significant digits round to the nearest IEEE-754 double); callers needing the full precision shouldCAST(... AS STRING)indatastore_search_sql.INT64->int) and FLOAT64 paths were already correct — only the Decimal branch changed.Test plan
pytest tests/test_streaming.py— three streaming tests green.pytest tests/— full 333-test suite green.tests/test_streaming.pynow assertsisinstance(record_value, float)explicitly so a regression to strings fails loudly.Summary by CodeRabbit
Bug Fixes