Skip to content

Commit 890b6d5

Browse files
committed
Fix for enum type duplication in graphene schema
The converter code was created a new type for each Enum column that it encountered. The problem is where the same Enum type is used for multiple columns. In that case graphene will notice two schema types with the same underlying name and throw an Assertion error like: AssertionError: Found different types with the same name in the schema: pet_kind, pet_kind. This fix creates a new registry dict for storing a type.name to Enum mapping that allows for reuse.
1 parent 33d5b74 commit 890b6d5

File tree

3 files changed

+23
-6
lines changed

3 files changed

+23
-6
lines changed

graphene_sqlalchemy/converter.py

+13-5
Original file line numberDiff line numberDiff line change
@@ -146,12 +146,20 @@ def convert_column_to_float(type, column, registry=None):
146146

147147
@convert_sqlalchemy_type.register(types.Enum)
148148
def convert_enum_to_enum(type, column, registry=None):
149-
try:
150-
items = type.enum_class.__members__.items()
151-
except AttributeError:
152-
items = zip(type.enums, type.enums)
149+
enum_type = None
150+
if registry is not None:
151+
enum_type = registry.get_type_for_enum(type.name)
152+
if enum_type is None:
153+
try:
154+
items = type.enum_class.__members__.items()
155+
except AttributeError:
156+
items = zip(type.enums, type.enums)
157+
enum_type = Enum(type.name, items)
158+
if registry is not None:
159+
registry.register_type_for_enum(type.name, enum_type)
160+
153161
return Field(
154-
Enum(type.name, items),
162+
enum_type,
155163
description=get_column_doc(column),
156164
required=not (is_column_nullable(column)),
157165
)

graphene_sqlalchemy/registry.py

+7
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ def __init__(self):
33
self._registry = {}
44
self._registry_models = {}
55
self._registry_composites = {}
6+
self._registry_enums = {}
67

78
def register(self, cls):
89
from .types import SQLAlchemyObjectType
@@ -27,6 +28,12 @@ def register_composite_converter(self, composite, converter):
2728
def get_converter_for_composite(self, composite):
2829
return self._registry_composites.get(composite)
2930

31+
def register_type_for_enum(self, enum_type_name, graphene_enum):
32+
self._registry_enums[enum_type_name] = graphene_enum
33+
34+
def get_type_for_enum(self, enum_type_name):
35+
return self._registry_enums.get(enum_type_name)
36+
3037

3138
registry = None
3239

graphene_sqlalchemy/tests/models.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,14 @@ class Editor(Base):
2121
editor_id = Column(Integer(), primary_key=True)
2222
name = Column(String(100))
2323

24+
PetKindEnum = Enum("cat", "dog", name="pet_kind")
2425

2526
class Pet(Base):
2627
__tablename__ = "pets"
2728
id = Column(Integer(), primary_key=True)
2829
name = Column(String(30))
29-
pet_kind = Column(Enum("cat", "dog", name="pet_kind"), nullable=False)
30+
pet_kind = Column(PetKindEnum, nullable=False)
31+
pet_kind_again = Column(PetKindEnum)
3032
reporter_id = Column(Integer(), ForeignKey("reporters.id"))
3133

3234

0 commit comments

Comments
 (0)