Skip to content

Commit 004bbf4

Browse files
author
Julien Nakache
committed
tests pass
test pass
1 parent d00d9a0 commit 004bbf4

File tree

5 files changed

+106
-48
lines changed

5 files changed

+106
-48
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
@@ -6,7 +6,7 @@
66
from graphene import ID, Boolean, Dynamic, Enum, Field, Float, Int, List, String
77
from graphene.types.json import JSONString
88

9-
from .fields import createConnectionField
9+
from .fields import create_connection_field
1010

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

4040
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
from promise import is_thenable, Promise
34
from sqlalchemy.orm.query import Query
@@ -9,6 +10,9 @@
910
from .utils import get_query, sort_argument_for_model
1011

1112

13+
log = logging.getLogger()
14+
15+
1216
class UnsortedSQLAlchemyConnectionField(ConnectionField):
1317
@property
1418
def type(self):
@@ -94,18 +98,46 @@ def __init__(self, type, *args, **kwargs):
9498
super(SQLAlchemyConnectionField, self).__init__(type, *args, **kwargs)
9599

96100

97-
__connectionFactory = UnsortedSQLAlchemyConnectionField
101+
def default_connection_field_factory(relationship, registry):
102+
model = relationship.mapper.entity
103+
_type = registry.get_type_for_model(model)
104+
return UnsortedSQLAlchemyConnectionField(_type._meta.connection)
105+
106+
107+
__connection_field_factory = default_connection_field_factory
98108

109+
def create_connection_field(relationship, registry):
110+
return __connection_field_factory(relationship, registry)
99111

100-
def createConnectionField(_type):
101-
return __connectionFactory(_type)
112+
def register_connection_field_factory(connection_factory):
113+
global __connection_field_factory
114+
__connection_field_factory = connection_factory
102115

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

104123
def registerConnectionFieldFactory(factoryMethod):
105-
global __connectionFactory
106-
__connectionFactory = factoryMethod
124+
log.warn(
125+
'registerConnectionFieldFactory is deprecated and will be removed in the next '
126+
'major version. Use register_connection_field_factory instead.'
127+
)
128+
129+
def old_factory_method_wrapper(relationship, registry):
130+
model = relationship.mapper.entity
131+
_type = registry.get_type_for_model(model)
132+
return factoryMethod(_type)
133+
134+
register_connection_field_factory(old_factory_method_wrapper)
107135

108136

109137
def unregisterConnectionFieldFactory():
110-
global __connectionFactory
111-
__connectionFactory = UnsortedSQLAlchemyConnectionField
138+
log.warn(
139+
'registerConnectionFieldFactory is deprecated and will be removed in the next '
140+
'major version. Use unregister_connection_field_factory instead.'
141+
)
142+
143+
unregister_connection_field_factory()
Lines changed: 63 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,69 @@
11
from graphene_sqlalchemy.fields import (
22
SQLAlchemyConnectionField,
3+
register_connection_field_factory,
4+
unregister_connection_field_factory,
35
registerConnectionFieldFactory,
46
unregisterConnectionFieldFactory,
57
)
6-
import graphene
7-
8-
9-
def test_register():
10-
class LXConnectionField(SQLAlchemyConnectionField):
11-
@classmethod
12-
def _applyQueryArgs(cls, model, q, args):
13-
return q
14-
15-
@classmethod
16-
def connection_resolver(
17-
cls, resolver, connection, model, root, args, context, info
18-
):
19-
def LXResolver(root, args, context, info):
20-
iterable = resolver(root, args, context, info)
21-
if iterable is None:
22-
iterable = cls.get_query(model, context, info, args)
23-
24-
# We accept always a query here. All LX-queries can be filtered and sorted
25-
iterable = cls._applyQueryArgs(model, iterable, args)
26-
return iterable
27-
28-
return SQLAlchemyConnectionField.connection_resolver(
29-
LXResolver, connection, model, root, args, context, info
30-
)
31-
32-
def createLXConnectionField(table):
33-
class LXConnection(graphene.relay.Connection):
34-
class Meta:
35-
node = table
36-
37-
return LXConnectionField(
38-
LXConnection,
39-
filter=table.filter(),
40-
order_by=graphene.List(of_type=table.order_by),
41-
)
42-
43-
registerConnectionFieldFactory(createLXConnectionField)
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)
4466
unregisterConnectionFieldFactory()
67+
types = define_types()
68+
69+
assert not isinstance(types['ReporterType']._meta.fields['articles'].type(), SQLAlchemyConnectionField)

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,5 +42,5 @@
4242
"SQLAlchemy",
4343
"singledispatch>=3.4.0.3",
4444
],
45-
tests_require=["pytest>=2.7.2", "mock", "sqlalchemy_utils"],
45+
tests_require=["pytest>=2.7.2", "mock", "sqlalchemy_utils", "enum34"],
4646
)

0 commit comments

Comments
 (0)