Skip to content

Commit 791a167

Browse files
committed
Merge branch 'master' into features/2.0
# Conflicts: # graphene_sqlalchemy/types.py
2 parents d39871b + c2da407 commit 791a167

File tree

4 files changed

+58
-7
lines changed

4 files changed

+58
-7
lines changed

graphene_sqlalchemy/tests/models.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
from sqlalchemy import Column, Date, ForeignKey, Integer, String, Table
44
from sqlalchemy.ext.declarative import declarative_base
5-
from sqlalchemy.orm import relationship
5+
from sqlalchemy.orm import mapper, relationship
66

77
Base = declarative_base()
88

@@ -47,3 +47,14 @@ class Article(Base):
4747
headline = Column(String(100))
4848
pub_date = Column(Date())
4949
reporter_id = Column(Integer(), ForeignKey('reporters.id'))
50+
51+
52+
class ReflectedEditor(type):
53+
"""Same as Editor, but using reflected table."""
54+
@classmethod
55+
def __subclasses__(cls):
56+
return []
57+
58+
editor_table = Table('editors', Base.metadata, autoload=True)
59+
60+
mapper(ReflectedEditor, editor_table)
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
2+
from graphene import ObjectType
3+
4+
from ..registry import Registry
5+
from ..types import SQLAlchemyObjectType
6+
from .models import ReflectedEditor
7+
8+
registry = Registry()
9+
10+
11+
class Reflected(SQLAlchemyObjectType):
12+
13+
class Meta:
14+
model = ReflectedEditor
15+
registry = registry
16+
17+
18+
def test_objecttype_registered():
19+
assert issubclass(Reflected, ObjectType)
20+
assert Reflected._meta.model == ReflectedEditor
21+
assert list(
22+
Reflected._meta.fields.keys()) == ['editor_id', 'name']
23+
24+

graphene_sqlalchemy/types.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
convert_sqlalchemy_relationship,
1515
convert_sqlalchemy_hybrid_method)
1616
from .registry import Registry, get_global_registry
17-
from .utils import get_query, is_mapped
17+
from .utils import get_query, is_mapped_class, is_mapped_instance
1818

1919

2020
def construct_fields(model, registry, only_fields, exclude_fields):
@@ -90,7 +90,7 @@ class SQLAlchemyObjectType(ObjectType):
9090
def __init_subclass_with_meta__(cls, model=None, registry=None, skip_registry=False,
9191
only_fields=(), exclude_fields=(), connection=None,
9292
use_connection=None, interfaces=(), id=None, **options):
93-
assert is_mapped(model), (
93+
assert is_mapped_class(model), (
9494
'You need to pass a valid SQLAlchemy Model in '
9595
'{}.Meta, received "{}".'
9696
).format(cls.__name__, model)
@@ -136,7 +136,7 @@ def __init_subclass_with_meta__(cls, model=None, registry=None, skip_registry=Fa
136136
def is_type_of(cls, root, context, info):
137137
if isinstance(root, cls):
138138
return True
139-
if not is_mapped(type(root)):
139+
if not is_mapped_instance(root):
140140
raise Exception((
141141
'Received incompatible instance "{}".'
142142
).format(root))

graphene_sqlalchemy/utils.py

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
from sqlalchemy.ext.declarative.api import DeclarativeMeta
1+
from sqlalchemy.exc import ArgumentError
2+
from sqlalchemy.orm import class_mapper, object_mapper
3+
from sqlalchemy.orm.exc import UnmappedClassError, UnmappedInstanceError
24

35

46
def get_session(context):
@@ -16,5 +18,19 @@ def get_query(model, context):
1618
return query
1719

1820

19-
def is_mapped(obj):
20-
return isinstance(obj, DeclarativeMeta)
21+
def is_mapped_class(cls):
22+
try:
23+
class_mapper(cls)
24+
except (ArgumentError, UnmappedClassError):
25+
return False
26+
else:
27+
return True
28+
29+
30+
def is_mapped_instance(cls):
31+
try:
32+
object_mapper(cls)
33+
except (ArgumentError, UnmappedInstanceError):
34+
return False
35+
else:
36+
return True

0 commit comments

Comments
 (0)