Skip to content

Commit ea98709

Browse files
committed
Proper support for the SQLAlchemy Enum type
1 parent 1d353f7 commit ea98709

File tree

4 files changed

+74
-8
lines changed

4 files changed

+74
-8
lines changed

graphene_sqlalchemy/converter.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,8 +98,6 @@ def convert_sqlalchemy_type(type, column, registry=None):
9898
@convert_sqlalchemy_type.register(types.Text)
9999
@convert_sqlalchemy_type.register(types.Unicode)
100100
@convert_sqlalchemy_type.register(types.UnicodeText)
101-
@convert_sqlalchemy_type.register(types.Enum)
102-
@convert_sqlalchemy_type.register(postgresql.ENUM)
103101
@convert_sqlalchemy_type.register(postgresql.UUID)
104102
@convert_sqlalchemy_type.register(TSVectorType)
105103
def convert_column_to_string(type, column, registry=None):
@@ -136,6 +134,16 @@ def convert_column_to_float(type, column, registry=None):
136134
return Float(description=get_column_doc(column), required=not(is_column_nullable(column)))
137135

138136

137+
@convert_sqlalchemy_type.register(types.Enum)
138+
def convert_enum_to_enum(type, column, registry=None):
139+
try:
140+
items = type.enum_class.__members__.items()
141+
except AttributeError:
142+
items = zip(type.enums, type.enums)
143+
return Field(Enum(type.name, items),
144+
description=get_column_doc(column), required=not(is_column_nullable(column)))
145+
146+
139147
@convert_sqlalchemy_type.register(ChoiceType)
140148
def convert_column_to_enum(type, column, registry=None):
141149
name = '{}_{}'.format(column.table.name, column.name).upper()

graphene_sqlalchemy/tests/models.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
from __future__ import absolute_import
22

3-
from sqlalchemy import Column, Date, ForeignKey, Integer, String, Table
3+
import enum
4+
5+
from sqlalchemy import Column, Date, Enum, ForeignKey, Integer, String, Table
46
from sqlalchemy.ext.declarative import declarative_base
57
from sqlalchemy.orm import mapper, relationship
68

@@ -21,6 +23,7 @@ class Pet(Base):
2123
__tablename__ = 'pets'
2224
id = Column(Integer(), primary_key=True)
2325
name = Column(String(30))
26+
pet_kind = Column(Enum('cat', 'dog', name='pet_kind'), nullable=False)
2427
reporter_id = Column(Integer(), ForeignKey('reporters.id'))
2528

2629

graphene_sqlalchemy/tests/test_converter.py

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import enum
2+
13
from py.test import raises
24
from sqlalchemy import Column, Table, case, types, select, func
35
from sqlalchemy.dialects import postgresql
@@ -24,7 +26,8 @@ def assert_column_conversion(sqlalchemy_type, graphene_field, **kwargs):
2426
column = Column(sqlalchemy_type, doc='Custom Help Text', **kwargs)
2527
graphene_type = convert_sqlalchemy_column(column)
2628
assert isinstance(graphene_type, graphene_field)
27-
field = graphene_type.Field()
29+
field = graphene_type if isinstance(
30+
graphene_type, graphene.Field) else graphene_type.Field()
2831
assert field.description == 'Custom Help Text'
2932
return field
3033

@@ -76,8 +79,18 @@ def test_should_unicodetext_convert_string():
7679
assert_column_conversion(types.UnicodeText(), graphene.String)
7780

7881

79-
def test_should_enum_convert_string():
80-
assert_column_conversion(types.Enum(), graphene.String)
82+
def test_should_enum_convert_enum():
83+
field = assert_column_conversion(
84+
types.Enum(enum.Enum('one', 'two')), graphene.Field)
85+
field_type = field.type()
86+
assert isinstance(field_type, graphene.Enum)
87+
assert hasattr(field_type, 'two')
88+
field = assert_column_conversion(
89+
types.Enum('one', 'two', name='two_numbers'), graphene.Field)
90+
field_type = field.type()
91+
assert field_type.__class__.__name__ == 'two_numbers'
92+
assert isinstance(field_type, graphene.Enum)
93+
assert hasattr(field_type, 'two')
8194

8295

8396
def test_should_small_integer_convert_int():
@@ -119,6 +132,7 @@ def test_should_label_convert_int():
119132
graphene_type = convert_sqlalchemy_column(label)
120133
assert isinstance(graphene_type, graphene.Int)
121134

135+
122136
def test_should_choice_convert_enum():
123137
TYPES = [
124138
(u'es', u'Spanish'),
@@ -247,7 +261,12 @@ def test_should_postgresql_uuid_convert():
247261

248262

249263
def test_should_postgresql_enum_convert():
250-
assert_column_conversion(postgresql.ENUM(), graphene.String)
264+
field = assert_column_conversion(postgresql.ENUM(
265+
enum.Enum('one', 'two'), name='two_numbers'), graphene.Field)
266+
field_type = field.type()
267+
assert field_type.__class__.__name__ == 'two_numbers'
268+
assert isinstance(field_type, graphene.Enum)
269+
assert hasattr(field_type, 'two')
251270

252271

253272
def test_should_postgresql_array_convert():

graphene_sqlalchemy/tests/test_query.py

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from ..registry import reset_global_registry
99
from ..fields import SQLAlchemyConnectionField
1010
from ..types import SQLAlchemyObjectType
11-
from .models import Article, Base, Editor, Reporter
11+
from .models import Article, Base, Editor, Pet, Reporter
1212

1313
db = create_engine('sqlite:///test_sqlalchemy.sqlite3')
1414

@@ -33,6 +33,8 @@ def session():
3333

3434

3535
def setup_fixtures(session):
36+
pet = Pet(name='Lassie', pet_kind='dog')
37+
session.add(pet)
3638
reporter = Reporter(first_name='ABA', last_name='X')
3739
session.add(reporter)
3840
reporter2 = Reporter(first_name='ABO', last_name='Y')
@@ -93,6 +95,40 @@ def resolve_reporters(self, *args, **kwargs):
9395
assert result.data == expected
9496

9597

98+
def test_should_query_enums(session):
99+
setup_fixtures(session)
100+
101+
class PetType(SQLAlchemyObjectType):
102+
103+
class Meta:
104+
model = Pet
105+
106+
class Query(graphene.ObjectType):
107+
pet = graphene.Field(PetType)
108+
109+
def resolve_pet(self, *args, **kwargs):
110+
return session.query(Pet).first()
111+
112+
query = '''
113+
query PetQuery {
114+
pet {
115+
name,
116+
petKind
117+
}
118+
}
119+
'''
120+
expected = {
121+
'pet': {
122+
'name': 'Lassie',
123+
'petKind': 'dog'
124+
}
125+
}
126+
schema = graphene.Schema(query=Query)
127+
result = schema.execute(query)
128+
assert not result.errors
129+
assert result.data == expected, result.data
130+
131+
96132
def test_should_node(session):
97133
setup_fixtures(session)
98134

0 commit comments

Comments
 (0)