Skip to content

Commit 0cd2ccf

Browse files
committed
added tests, updated docs, allow for subclassing SQLAlchemyObjectType
1 parent 0657bae commit 0cd2ccf

File tree

3 files changed

+45
-22
lines changed

3 files changed

+45
-22
lines changed

README.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,38 @@ query = '''
6868
result = schema.execute(query, context_value={'session': db_session})
6969
```
7070

71+
You may also subclass SQLAlchemyObjectType by providing `abstract = True` in
72+
your subclasses Meta:
73+
```python
74+
from graphene_sqlalchemy import SQLAlchemyObjectType
75+
76+
class ActiveSQLAlchemyObjectType(SQLAlchemyObjectType):
77+
class Meta:
78+
abstract = True
79+
80+
@classmethod
81+
def get_node(cls, id, context, info):
82+
return cls.get_query(context).\
83+
filter(and_(
84+
cls._meta.model.deleted_at==None,
85+
cls._meta.model.id==id,
86+
)).\
87+
first()
88+
89+
class User(ActiveSQLAlchemyObjectType):
90+
class Meta:
91+
model = UserModel
92+
93+
class Query(graphene.ObjectType):
94+
users = graphene.List(User)
95+
96+
def resolve_users(self, args, context, info):
97+
query = User.get_query(context) # SQLAlchemy query
98+
return query.all()
99+
100+
schema = graphene.Schema(query=Query)
101+
```
102+
71103
To learn more check out the following [examples](examples/):
72104

73105
* **Full example**: [Flask SQLAlchemy example](examples/flask_sqlalchemy)

graphene_sqlalchemy/tests/test_types.py

Lines changed: 4 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -79,25 +79,9 @@ def test_object_type():
7979

8080

8181
# Test Custom SQLAlchemyObjectType Implementation
82-
class CustomSQLAlchemyObjectType(six.with_metaclass(SQLAlchemyObjectTypeMeta, ObjectType)):
83-
@classmethod
84-
def is_type_of(cls, root, context, info):
85-
return SQLAlchemyObjectType.is_type_of(root, context, info)
86-
87-
@classmethod
88-
def get_query(cls, context):
89-
return SQLAlchemyObjectType.get_query(context)
90-
91-
@classmethod
92-
def get_node(cls, id, context, info):
93-
return SQLAlchemyObjectType.get_node(id, context, info)
94-
95-
@classmethod
96-
def resolve_id(self, args, context, info):
97-
graphene_type = info.parent_type.graphene_type
98-
if is_node(graphene_type):
99-
return self.__mapper__.primary_key_from_instance(self)[0]
100-
return getattr(self, graphene_type._meta.id, None)
82+
class CustomSQLAlchemyObjectType(SQLAlchemyObjectType):
83+
class Meta:
84+
abstract = True
10185

10286

10387
class CustomCharacter(CustomSQLAlchemyObjectType):
@@ -106,6 +90,7 @@ class Meta:
10690
model = Reporter
10791
registry = registry
10892

93+
10994
def test_custom_objecttype_registered():
11095
assert issubclass(CustomCharacter, ObjectType)
11196
assert CustomCharacter._meta.model == Reporter

graphene_sqlalchemy/types.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,9 +82,15 @@ def __new__(cls, name, bases, attrs):
8282
exclude_fields=(),
8383
id='id',
8484
interfaces=(),
85-
registry=None
85+
registry=None,
86+
abstract=False,
8687
)
8788

89+
cls = ObjectTypeMeta.__new__(cls, name, bases, dict(attrs, _meta=options))
90+
91+
if options.abstract:
92+
return cls
93+
8894
if not options.registry:
8995
options.registry = get_global_registry()
9096
assert isinstance(options.registry, Registry), (
@@ -96,8 +102,6 @@ def __new__(cls, name, bases, attrs):
96102
'{}.Meta, received "{}".'
97103
).format(name, options.model)
98104

99-
cls = ObjectTypeMeta.__new__(cls, name, bases, dict(attrs, _meta=options))
100-
101105
options.registry.register(cls)
102106

103107
options.sqlalchemy_fields = yank_fields_from_attrs(
@@ -115,6 +119,8 @@ def __new__(cls, name, bases, attrs):
115119

116120

117121
class SQLAlchemyObjectType(six.with_metaclass(SQLAlchemyObjectTypeMeta, ObjectType)):
122+
class Meta:
123+
abstract = True
118124

119125
@classmethod
120126
def is_type_of(cls, root, context, info):

0 commit comments

Comments
 (0)