graphql-core's GraphQLFloat scalar rejects Python Decimal objects, which are the standard return type from database ORMs (SQLAlchemy, Django ORM, etc.) for:
- Numeric/Decimal column types
- Aggregate functions (SUM, AVG) even on Integer/Float columns
- Any high-precision arithmetic
Current Behavior:
from decimal import Decimal
from graphql import GraphQLFloat
GraphQLFloat.serialize(Decimal("123.45"))
# Raises: GraphQLError: Float cannot represent non numeric value: <Decimal instance>
Expected Behavior:
Decimal should be coerced to float, just as int is already accepted.
Why This Matters:
- Python's Decimal is a numeric type - it's part of the standard library for precise decimal arithmetic
- Database ORMs universally return Decimal for precision:
- SQLAlchemy: Numeric, DECIMAL columns → Decimal
- Django ORM: DecimalField → Decimal
- PostgreSQL aggregates often return NUMERIC → Decimal
- Precedent exists: GraphQLInt already accepts bool (coerces True/False → 1/0)
- Backwards compatibility: Earlier versions were more lenient
Workarounds:
- Manually float() every Decimal in resolvers (verbose, error-prone)
- Monkey-patch GraphQLFloat (fragile)
- Custom scalar type (requires client-side changes)
Impact:
Every Python GraphQL server using database ORMs must implement workarounds. This makes graphql-core less pythonic and forces type coercion at the application layer.
Environment:
- graphql-core: 3.x
- Python: 3.12
graphql-core's GraphQLFloat scalar rejects Python Decimal objects, which are the standard return type from database ORMs (SQLAlchemy, Django ORM, etc.) for:
Current Behavior:
Expected Behavior:
Decimal should be coerced to float, just as int is already accepted.
Why This Matters:
Workarounds:
Impact:
Every Python GraphQL server using database ORMs must implement workarounds. This makes graphql-core less pythonic and forces type coercion at the application layer.
Environment: