Skip to content

Commit d83f7e1

Browse files
committed
Support Decimal() type.
1 parent a7e8a1b commit d83f7e1

File tree

3 files changed

+23
-1
lines changed

3 files changed

+23
-1
lines changed

graphene_sqlalchemy/converter.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import datetime
22
import typing
3+
from decimal import Decimal
34
from functools import singledispatch
45
from typing import Any
56

@@ -288,6 +289,14 @@ def convert_hybrid_property_return_type_inner_float(arg):
288289
return Float
289290

290291

292+
@convert_hybrid_property_return_type_inner.register(value_equals(Decimal))
293+
def convert_hybrid_property_return_type_inner_decimal(arg):
294+
# The reason Decimal should be serialized as a String is because this is a
295+
# base10 type used in things like money, and string allows it to not
296+
# lose precision (which would happen if we downcasted to a Float, for example)
297+
return String
298+
299+
291300
@convert_hybrid_property_return_type_inner.register(value_equals(bool))
292301
def convert_hybrid_property_return_type_inner_bool(arg):
293302
return Boolean

graphene_sqlalchemy/tests/models.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import datetime
44
import enum
5+
from decimal import Decimal
56
from typing import List
67

78
from sqlalchemy import (Column, Date, Enum, ForeignKey, Integer, String, Table,
@@ -115,6 +116,10 @@ def hybrid_prop_time(self) -> datetime.time:
115116
def hybrid_prop_datetime(self) -> datetime.datetime:
116117
return datetime.datetime.now()
117118

119+
@hybrid_property
120+
def hybrid_prop_decimal(self) -> Decimal:
121+
return Decimal("3.14")
122+
118123
@hybrid_property
119124
def hybrid_prop_first_article(self) -> Article:
120125
return self.articles[0]

graphene_sqlalchemy/tests/test_types.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ class Meta:
106106
"hybrid_prop_date",
107107
"hybrid_prop_time",
108108
"hybrid_prop_datetime",
109+
"hybrid_prop_decimal",
109110
"hybrid_prop_first_article",
110111
# Relationship
111112
"pets",
@@ -174,6 +175,11 @@ class Meta:
174175
assert hybrid_prop_datetime.type == DateTime
175176
assert hybrid_prop_datetime.description is None # "doc" is ignored by hybrid_property
176177

178+
hybrid_prop_decimal = ReporterType._meta.fields['hybrid_prop_decimal']
179+
# Decimal (base10) should serialize to String for correctness.
180+
assert hybrid_prop_decimal.type == String
181+
assert hybrid_prop_decimal.description is None # "doc" is ignored by hybrid_property
182+
177183
# relationship
178184
favorite_article_field = ReporterType._meta.fields['favorite_article']
179185
assert isinstance(favorite_article_field, Dynamic)
@@ -251,6 +257,7 @@ class Meta:
251257
"hybrid_prop_date",
252258
"hybrid_prop_time",
253259
"hybrid_prop_datetime",
260+
"hybrid_prop_decimal",
254261
"hybrid_prop_first_article",
255262
])
256263

@@ -367,6 +374,7 @@ class Meta:
367374
"hybrid_prop_date",
368375
"hybrid_prop_time",
369376
"hybrid_prop_datetime",
377+
"hybrid_prop_decimal",
370378
"hybrid_prop_first_article",
371379
])
372380

@@ -488,7 +496,7 @@ class Meta:
488496

489497
assert issubclass(CustomReporterType, ObjectType)
490498
assert CustomReporterType._meta.model == Reporter
491-
assert len(CustomReporterType._meta.fields) == 21
499+
assert len(CustomReporterType._meta.fields) == 22
492500

493501

494502
# Test Custom SQLAlchemyObjectType with Custom Options

0 commit comments

Comments
 (0)