Skip to content

Commit eb625bb

Browse files
author
Julien Nakache
committed
tests pass
test pass
1 parent c9af40c commit eb625bb

File tree

5 files changed

+120
-50
lines changed

5 files changed

+120
-50
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ htmlcov/
4545
nosetests.xml
4646
coverage.xml
4747
*,cover
48+
.pytest_cache/
4849

4950
# Translations
5051
*.mo

graphene_sqlalchemy/converter.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
String)
88
from graphene.types.json import JSONString
99

10-
from .fields import createConnectionField
10+
from .fields import create_connection_field
1111

1212
try:
1313
from sqlalchemy_utils import ChoiceType, JSONType, ScalarListType, TSVectorType
@@ -35,7 +35,7 @@ def dynamic_type():
3535
return Field(_type)
3636
elif direction in (interfaces.ONETOMANY, interfaces.MANYTOMANY):
3737
if _type._meta.connection:
38-
return createConnectionField(_type._meta.connection)
38+
return create_connection_field(relationship, registry)
3939
return Field(List(_type))
4040

4141
return Dynamic(dynamic_type)

graphene_sqlalchemy/fields.py

Lines changed: 39 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import logging
12
from functools import partial
23

34
from promise import Promise, is_thenable
@@ -10,6 +11,9 @@
1011
from .utils import get_query, sort_argument_for_model
1112

1213

14+
log = logging.getLogger()
15+
16+
1317
class UnsortedSQLAlchemyConnectionField(ConnectionField):
1418
@property
1519
def type(self):
@@ -95,18 +99,46 @@ def __init__(self, type, *args, **kwargs):
9599
super(SQLAlchemyConnectionField, self).__init__(type, *args, **kwargs)
96100

97101

98-
__connectionFactory = UnsortedSQLAlchemyConnectionField
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
99109

110+
def create_connection_field(relationship, registry):
111+
return __connection_field_factory(relationship, registry)
100112

101-
def createConnectionField(_type):
102-
return __connectionFactory(_type)
113+
def register_connection_field_factory(connection_factory):
114+
global __connection_field_factory
115+
__connection_field_factory = connection_factory
103116

117+
def unregister_connection_field_factory():
118+
global __connection_field_factory
119+
__connection_field_factory = default_connection_field_factory
120+
121+
122+
# TODO Remove in next major version
104123

105124
def registerConnectionFieldFactory(factoryMethod):
106-
global __connectionFactory
107-
__connectionFactory = factoryMethod
125+
log.warn(
126+
'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)
108136

109137

110138
def unregisterConnectionFieldFactory():
111-
global __connectionFactory
112-
__connectionFactory = UnsortedSQLAlchemyConnectionField
139+
log.warn(
140+
'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()
Lines changed: 68 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,69 @@
1-
import graphene
2-
from graphene_sqlalchemy.fields import (SQLAlchemyConnectionField,
3-
registerConnectionFieldFactory,
4-
unregisterConnectionFieldFactory)
5-
6-
7-
def test_register():
8-
class LXConnectionField(SQLAlchemyConnectionField):
9-
@classmethod
10-
def _applyQueryArgs(cls, model, q, args):
11-
return q
12-
13-
@classmethod
14-
def connection_resolver(
15-
cls, resolver, connection, model, root, args, context, info
16-
):
17-
def LXResolver(root, args, context, info):
18-
iterable = resolver(root, args, context, info)
19-
if iterable is None:
20-
iterable = cls.get_query(model, context, info, args)
21-
22-
# We accept always a query here. All LX-queries can be filtered and sorted
23-
iterable = cls._applyQueryArgs(model, iterable, args)
24-
return iterable
25-
26-
return SQLAlchemyConnectionField.connection_resolver(
27-
LXResolver, connection, model, root, args, context, info
28-
)
29-
30-
def createLXConnectionField(table):
31-
class LXConnection(graphene.relay.Connection):
32-
class Meta:
33-
node = table
34-
35-
return LXConnectionField(
36-
LXConnection,
37-
filter=table.filter(),
38-
order_by=graphene.List(of_type=table.order_by),
39-
)
40-
41-
registerConnectionFieldFactory(createLXConnectionField)
1+
from graphene_sqlalchemy.fields import (
2+
SQLAlchemyConnectionField,
3+
register_connection_field_factory,
4+
unregister_connection_field_factory,
5+
registerConnectionFieldFactory,
6+
unregisterConnectionFieldFactory,
7+
)
8+
from graphene_sqlalchemy.types import SQLAlchemyObjectType
9+
from graphene_sqlalchemy.tests.models import Article, Reporter
10+
from graphene_sqlalchemy.registry import Registry
11+
from graphene import Connection, Node
12+
13+
14+
def define_types():
15+
_registry = Registry()
16+
17+
class ReporterType(SQLAlchemyObjectType):
18+
class Meta:
19+
model = Reporter
20+
registry = _registry
21+
interfaces = (Node,)
22+
23+
24+
class ArticleType(SQLAlchemyObjectType):
25+
class Meta:
26+
model = Article
27+
registry = _registry
28+
interfaces = (Node,)
29+
30+
return {
31+
'ReporterType': ReporterType,
32+
'ArticleType': ArticleType,
33+
}
34+
35+
36+
def test_register_connection_field_factory():
37+
def connection_field_factory(relationship, registry):
38+
model = relationship.mapper.entity
39+
_type = registry.get_type_for_model(model)
40+
return SQLAlchemyConnectionField(_type._meta.connection)
41+
42+
register_connection_field_factory(connection_field_factory)
43+
44+
types = define_types()
45+
46+
assert isinstance(types['ReporterType']._meta.fields['articles'].type(), SQLAlchemyConnectionField)
47+
48+
49+
def test_unregister_connection_field_factory():
50+
register_connection_field_factory(lambda: None)
51+
unregister_connection_field_factory()
52+
53+
types = define_types()
54+
55+
assert not isinstance(types['ReporterType']._meta.fields['articles'].type(), SQLAlchemyConnectionField)
56+
57+
58+
def test_deprecated_registerConnectionFieldFactory():
59+
registerConnectionFieldFactory(SQLAlchemyConnectionField)
60+
types = define_types()
61+
assert isinstance(types['ReporterType']._meta.fields['articles'].type(), SQLAlchemyConnectionField)
62+
63+
64+
def test_deprecated_unregisterConnectionFieldFactory():
65+
registerConnectionFieldFactory(SQLAlchemyConnectionField)
4266
unregisterConnectionFieldFactory()
67+
types = define_types()
68+
69+
assert not isinstance(types['ReporterType']._meta.fields['articles'].type(), SQLAlchemyConnectionField)

setup.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
],
5757
keywords="api graphql protocol rest relay graphene",
5858
packages=find_packages(exclude=["tests"]),
59+
<<<<<<< HEAD
5960
install_requires=requirements,
6061
extras_require={
6162
"dev": [
@@ -66,4 +67,13 @@
6667
"test": tests_require,
6768
},
6869
tests_require=tests_require,
70+
=======
71+
install_requires=[
72+
"six>=1.10.0",
73+
"graphene>=2.1.3",
74+
"SQLAlchemy",
75+
"singledispatch>=3.4.0.3",
76+
],
77+
tests_require=["pytest>=2.7.2", "mock", "sqlalchemy_utils", "enum34"],
78+
>>>>>>> tests pass
6979
)

0 commit comments

Comments
 (0)