Skip to content

Commit dc7e2bb

Browse files
author
Julien Nakache
committed
rebase, move to meta and address comments
1 parent b9bd42d commit dc7e2bb

File tree

5 files changed

+135
-111
lines changed

5 files changed

+135
-111
lines changed

Diff for: graphene_sqlalchemy/converter.py

+2-4
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@
77
String)
88
from graphene.types.json import JSONString
99

10-
from .fields import create_connection_field
11-
1210
try:
1311
from sqlalchemy_utils import ChoiceType, JSONType, ScalarListType, TSVectorType
1412
except ImportError:
@@ -23,7 +21,7 @@ def is_column_nullable(column):
2321
return bool(getattr(column, "nullable", True))
2422

2523

26-
def convert_sqlalchemy_relationship(relationship, registry):
24+
def convert_sqlalchemy_relationship(relationship, registry, connection_field_factory):
2725
direction = relationship.direction
2826
model = relationship.mapper.entity
2927

@@ -35,7 +33,7 @@ def dynamic_type():
3533
return Field(_type)
3634
elif direction in (interfaces.ONETOMANY, interfaces.MANYTOMANY):
3735
if _type._meta.connection:
38-
return create_connection_field(relationship, registry)
36+
return connection_field_factory(relationship, registry)
3937
return Field(List(_type))
4038

4139
return Dynamic(dynamic_type)

Diff for: graphene_sqlalchemy/fields.py

+26-32
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010

1111
from .utils import get_query, sort_argument_for_model
1212

13-
1413
log = logging.getLogger()
1514

1615

@@ -99,46 +98,41 @@ def __init__(self, type, *args, **kwargs):
9998
super(SQLAlchemyConnectionField, self).__init__(type, *args, **kwargs)
10099

101100

102-
def default_connection_field_factory(relationship, registry):
103-
model = relationship.mapper.entity
104-
_type = registry.get_type_for_model(model)
105-
return UnsortedSQLAlchemyConnectionField(_type._meta.connection)
106-
107-
108-
__connection_field_factory = default_connection_field_factory
109-
110-
def create_connection_field(relationship, registry):
111-
return __connection_field_factory(relationship, registry)
101+
# TODO Remove in next major version
102+
__connectionFactory = UnsortedSQLAlchemyConnectionField
112103

113-
def register_connection_field_factory(connection_factory):
114-
global __connection_field_factory
115-
__connection_field_factory = connection_factory
116104

117-
def unregister_connection_field_factory():
118-
global __connection_field_factory
119-
__connection_field_factory = default_connection_field_factory
105+
def createConnectionField(_type):
106+
log.warn(
107+
'createConnectionField is deprecated and will be removed in the next '
108+
'major version. Use TODO instead.'
109+
)
110+
return __connectionFactory(_type)
120111

121112

122-
# TODO Remove in next major version
123-
124113
def registerConnectionFieldFactory(factoryMethod):
125114
log.warn(
126115
'registerConnectionFieldFactory is deprecated and will be removed in the next '
127-
'major version. Use register_connection_field_factory instead.'
128-
)
129-
130-
def old_factory_method_wrapper(relationship, registry):
131-
model = relationship.mapper.entity
132-
_type = registry.get_type_for_model(model)
133-
return factoryMethod(_type)
134-
135-
register_connection_field_factory(old_factory_method_wrapper)
116+
'major version. Use TODO instead.'
117+
)
118+
global __connectionFactory
119+
__connectionFactory = factoryMethod
136120

137121

138122
def unregisterConnectionFieldFactory():
139123
log.warn(
140124
'registerConnectionFieldFactory is deprecated and will be removed in the next '
141-
'major version. Use unregister_connection_field_factory instead.'
142-
)
143-
144-
unregister_connection_field_factory()
125+
'major version. Use TODO instead.'
126+
)
127+
global __connectionFactory
128+
__connectionFactory = UnsortedSQLAlchemyConnectionField
129+
130+
131+
def default_connection_field_factory(relationship, registry):
132+
log.warn(
133+
'This is deprecated and will be removed in the next '
134+
'major version. Use TODO instead.'
135+
)
136+
model = relationship.mapper.entity
137+
model_type = registry.get_type_for_model(model)
138+
return createConnectionField(model_type)

Diff for: graphene_sqlalchemy/tests/test_connectionfactory.py

-69
This file was deleted.

Diff for: graphene_sqlalchemy/tests/test_types.py

+95-3
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,13 @@
33
import six # noqa F401
44
from promise import Promise
55

6-
from graphene import Field, Int, Interface, ObjectType
7-
from graphene.relay import Connection, Node, is_node
6+
from graphene import (Connection, Field, Int, Interface, Node, ObjectType,
7+
is_node)
88

9-
from ..fields import SQLAlchemyConnectionField
9+
from ..fields import (SQLAlchemyConnectionField,
10+
UnsortedSQLAlchemyConnectionField,
11+
registerConnectionFieldFactory,
12+
unregisterConnectionFieldFactory)
1013
from ..registry import Registry
1114
from ..types import SQLAlchemyObjectType, SQLAlchemyObjectTypeOptions
1215
from .models import Article, Reporter
@@ -185,3 +188,92 @@ def resolver(*args, **kwargs):
185188
resolver, TestConnection, ReporterWithCustomOptions, None, None
186189
)
187190
assert result is not None
191+
192+
193+
# Tests for connection_field_factory
194+
195+
class _TestSQLAlchemyConnectionField(SQLAlchemyConnectionField):
196+
pass
197+
198+
199+
def test_default_connection_field_factory():
200+
_registry = Registry()
201+
202+
class ReporterType(SQLAlchemyObjectType):
203+
class Meta:
204+
model = Reporter
205+
registry = _registry
206+
interfaces = (Node,)
207+
208+
class ArticleType(SQLAlchemyObjectType):
209+
class Meta:
210+
model = Article
211+
registry = _registry
212+
interfaces = (Node,)
213+
214+
assert isinstance(ReporterType._meta.fields['articles'].type(), UnsortedSQLAlchemyConnectionField)
215+
216+
217+
def test_register_connection_field_factory():
218+
def test_connection_field_factory(relationship, registry):
219+
model = relationship.mapper.entity
220+
_type = registry.get_type_for_model(model)
221+
return _TestSQLAlchemyConnectionField(_type._meta.connection)
222+
223+
_registry = Registry()
224+
225+
class ReporterType(SQLAlchemyObjectType):
226+
class Meta:
227+
model = Reporter
228+
registry = _registry
229+
interfaces = (Node,)
230+
connection_field_factory = test_connection_field_factory
231+
232+
class ArticleType(SQLAlchemyObjectType):
233+
class Meta:
234+
model = Article
235+
registry = _registry
236+
interfaces = (Node,)
237+
238+
assert isinstance(ReporterType._meta.fields['articles'].type(), _TestSQLAlchemyConnectionField)
239+
240+
241+
def test_deprecated_registerConnectionFieldFactory():
242+
registerConnectionFieldFactory(_TestSQLAlchemyConnectionField)
243+
244+
_registry = Registry()
245+
246+
class ReporterType(SQLAlchemyObjectType):
247+
class Meta:
248+
model = Reporter
249+
registry = _registry
250+
interfaces = (Node,)
251+
252+
class ArticleType(SQLAlchemyObjectType):
253+
class Meta:
254+
model = Article
255+
registry = _registry
256+
interfaces = (Node,)
257+
258+
assert isinstance(ReporterType._meta.fields['articles'].type(), _TestSQLAlchemyConnectionField)
259+
260+
261+
def test_deprecated_unregisterConnectionFieldFactory():
262+
registerConnectionFieldFactory(_TestSQLAlchemyConnectionField)
263+
unregisterConnectionFieldFactory()
264+
265+
_registry = Registry()
266+
267+
class ReporterType(SQLAlchemyObjectType):
268+
class Meta:
269+
model = Reporter
270+
registry = _registry
271+
interfaces = (Node,)
272+
273+
class ArticleType(SQLAlchemyObjectType):
274+
class Meta:
275+
model = Article
276+
registry = _registry
277+
interfaces = (Node,)
278+
279+
assert not isinstance(ReporterType._meta.fields['articles'].type(), _TestSQLAlchemyConnectionField)

Diff for: graphene_sqlalchemy/types.py

+12-3
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,12 @@
1414
convert_sqlalchemy_composite,
1515
convert_sqlalchemy_hybrid_method,
1616
convert_sqlalchemy_relationship)
17+
from .fields import default_connection_field_factory
1718
from .registry import Registry, get_global_registry
1819
from .utils import get_query, is_mapped_class, is_mapped_instance
1920

2021

21-
def construct_fields(model, registry, only_fields, exclude_fields):
22+
def construct_fields(model, registry, only_fields, exclude_fields, connection_field_factory):
2223
inspected_model = sqlalchemyinspect(model)
2324

2425
fields = OrderedDict()
@@ -71,7 +72,7 @@ def construct_fields(model, registry, only_fields, exclude_fields):
7172
# We skip this field if we specify only_fields and is not
7273
# in there. Or when we exclude this field in exclude_fields
7374
continue
74-
converted_relationship = convert_sqlalchemy_relationship(relationship, registry)
75+
converted_relationship = convert_sqlalchemy_relationship(relationship, registry, connection_field_factory)
7576
name = relationship.key
7677
fields[name] = converted_relationship
7778

@@ -99,6 +100,7 @@ def __init_subclass_with_meta__(
99100
use_connection=None,
100101
interfaces=(),
101102
id=None,
103+
connection_field_factory=default_connection_field_factory,
102104
_meta=None,
103105
**options
104106
):
@@ -115,7 +117,14 @@ def __init_subclass_with_meta__(
115117
).format(cls.__name__, registry)
116118

117119
sqla_fields = yank_fields_from_attrs(
118-
construct_fields(model, registry, only_fields, exclude_fields), _as=Field
120+
construct_fields(
121+
model=model,
122+
registry=registry,
123+
only_fields=only_fields,
124+
exclude_fields=exclude_fields,
125+
connection_field_factory=connection_field_factory
126+
),
127+
_as=Field
119128
)
120129

121130
if use_connection is None and interfaces:

0 commit comments

Comments
 (0)