Skip to content

Commit

Permalink
Add SQLAlchemyList and SQLAlchemyMutation types
Browse files Browse the repository at this point in the history
This brings default support for fields filtering and ordering on queries and mutations.
  • Loading branch information
Toilal committed Nov 16, 2017
1 parent ecd9a91 commit 6945888
Show file tree
Hide file tree
Showing 5 changed files with 501 additions and 24 deletions.
27 changes: 27 additions & 0 deletions graphene_sqlalchemy/mutations.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
from graphene_sqlalchemy.types import SQLAlchemyMutation


def create(of_type):
class CreateModel(SQLAlchemyMutation):
class Meta:
model = of_type._meta.model
create = True
Output = of_type
return CreateModel.Field()


def update(of_type):
class UpdateModel(SQLAlchemyMutation):
class Meta:
model = of_type._meta.model
Output = of_type
return UpdateModel.Field()


def delete(of_type):
class DeleteModel(SQLAlchemyMutation):
class Meta:
model = of_type._meta.model
delete = True
Output = of_type
return DeleteModel.Field()
265 changes: 246 additions & 19 deletions graphene_sqlalchemy/tests/test_query.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

from ..registry import reset_global_registry
from ..fields import SQLAlchemyConnectionField
from ..types import SQLAlchemyObjectType
from ..types import SQLAlchemyObjectType, SQLAlchemyList
from .models import Article, Base, Editor, Reporter

db = create_engine('sqlite:///test_sqlalchemy.sqlite3')
Expand Down Expand Up @@ -45,11 +45,10 @@ def setup_fixtures(session):
session.commit()


def test_should_query_well(session):
def test_should_query_well_with_graphene_types(session):
setup_fixtures(session)

class ReporterType(SQLAlchemyObjectType):

class Meta:
model = Reporter

Expand Down Expand Up @@ -93,24 +92,257 @@ def resolve_reporters(self, *args, **kwargs):
assert result.data == expected


def test_should_filter_with_sqlalchemy_fields(session):
setup_fixtures(session)

class ReporterType(SQLAlchemyObjectType):
class Meta:
model = Reporter

class Query(graphene.ObjectType):
reporters = SQLAlchemyList(ReporterType)

query = '''
query ReporterQuery {
reporters(firstName: "ABA") {
firstName,
lastName,
email
}
}
'''
expected = {
'reporters': [{
'firstName': 'ABA',
'lastName': 'X',
'email': None
}]
}
schema = graphene.Schema(query=Query)
result = schema.execute(query, context_value={'session': session})
assert not result.errors
assert result.data == expected


def test_should_filter_with_custom_argument(session):
setup_fixtures(session)

class ReporterType(SQLAlchemyObjectType):
class Meta:
model = Reporter

class Query(graphene.ObjectType):
reporters = SQLAlchemyList(ReporterType, contains_o=graphene.Boolean())

def query_reporters(self, info, query, **kwargs):
return query.filter(Reporter.first_name.contains('O') == kwargs['contains_o'])

query = '''
query ReporterQuery {
reporters(lastName: "Y", containsO: true) {
firstName,
lastName,
email
}
}
'''
expected = {
'reporters': [{
'firstName': 'ABO',
'lastName': 'Y',
'email': None
}]
}
schema = graphene.Schema(query=Query)
result = schema.execute(query, context_value={'session': session})
assert not result.errors
assert result.data == expected

query = '''
query ReporterQuery {
reporters(containsO: false) {
firstName,
lastName,
email
}
}
'''
expected = {
'reporters': [{
'firstName': 'ABA',
'lastName': 'X',
'email': None
}]
}
schema = graphene.Schema(query=Query)
result = schema.execute(query, context_value={'session': session})
assert not result.errors
assert result.data == expected


def test_should_filter_with_custom_operator(session):
setup_fixtures(session)

class ReporterType(SQLAlchemyObjectType):
class Meta:
model = Reporter

class Query(graphene.ObjectType):
reporters = SQLAlchemyList(ReporterType, operator='like')

query = '''
query ReporterQuery {
reporters(firstName: "%BO%") {
firstName,
lastName,
email
}
}
'''
expected = {
'reporters': [{
'firstName': 'ABO',
'lastName': 'Y',
'email': None
}]
}
schema = graphene.Schema(query=Query)
result = schema.execute(query, context_value={'session': session})
assert not result.errors
assert result.data == expected


def test_should_order_by(session):
setup_fixtures(session)

class ReporterType(SQLAlchemyObjectType):
class Meta:
model = Reporter

class Query(graphene.ObjectType):
reporters = SQLAlchemyList(ReporterType, order_by='firstName')

query = '''
query ReporterQuery {
reporters {
firstName,
lastName,
email
}
}
'''
expected = {
'reporters': [{
'firstName': 'ABA',
'lastName': 'X',
'email': None
},
{
'firstName': 'ABO',
'lastName': 'Y',
'email': None
}]
}
schema = graphene.Schema(query=Query)
result = schema.execute(query, context_value={'session': session})
assert not result.errors
assert result.data == expected


def test_should_order_by_asc(session):
setup_fixtures(session)

class ReporterType(SQLAlchemyObjectType):
class Meta:
model = Reporter

class Query(graphene.ObjectType):
reporters = SQLAlchemyList(ReporterType, order_by='first_name ASC')

query = '''
query ReporterQuery {
reporters {
firstName,
lastName,
email
}
}
'''
expected = {
'reporters': [
{
'firstName': 'ABA',
'lastName': 'X',
'email': None
},
{
'firstName': 'ABO',
'lastName': 'Y',
'email': None
}
]
}
schema = graphene.Schema(query=Query)
result = schema.execute(query, context_value={'session': session})
assert not result.errors
assert result.data == expected


def test_should_order_by_desc(session):
setup_fixtures(session)

class ReporterType(SQLAlchemyObjectType):
class Meta:
model = Reporter

class Query(graphene.ObjectType):
reporters = SQLAlchemyList(ReporterType, order_by='firstName desc')

query = '''
query ReporterQuery {
reporters {
firstName,
lastName,
email
}
}
'''
expected = {
'reporters': [
{
'firstName': 'ABO',
'lastName': 'Y',
'email': None
},
{
'firstName': 'ABA',
'lastName': 'X',
'email': None
}
]
}
schema = graphene.Schema(query=Query)
result = schema.execute(query, context_value={'session': session})
assert not result.errors
assert result.data == expected


def test_should_node(session):
setup_fixtures(session)

class ReporterNode(SQLAlchemyObjectType):

class Meta:
model = Reporter
interfaces = (Node, )
interfaces = (Node,)

@classmethod
def get_node(cls, id, info):
return Reporter(id=2, first_name='Cookie Monster')

class ArticleNode(SQLAlchemyObjectType):

class Meta:
model = Article
interfaces = (Node, )
interfaces = (Node,)

# @classmethod
# def get_node(cls, id, info):
Expand Down Expand Up @@ -169,9 +401,9 @@ def resolve_article(self, *args, **kwargs):
'email': None,
'articles': {
'edges': [{
'node': {
'headline': 'Hi!'
}
'node': {
'headline': 'Hi!'
}
}]
},
},
Expand All @@ -197,10 +429,9 @@ def test_should_custom_identifier(session):
setup_fixtures(session)

class EditorNode(SQLAlchemyObjectType):

class Meta:
model = Editor
interfaces = (Node, )
interfaces = (Node,)

class Query(graphene.ObjectType):
node = Node.Field()
Expand Down Expand Up @@ -247,29 +478,25 @@ def test_should_mutate_well(session):
setup_fixtures(session)

class EditorNode(SQLAlchemyObjectType):

class Meta:
model = Editor
interfaces = (Node, )
interfaces = (Node,)

class ReporterNode(SQLAlchemyObjectType):

class Meta:
model = Reporter
interfaces = (Node, )
interfaces = (Node,)

@classmethod
def get_node(cls, id, info):
return Reporter(id=2, first_name='Cookie Monster')

class ArticleNode(SQLAlchemyObjectType):

class Meta:
model = Article
interfaces = (Node, )
interfaces = (Node,)

class CreateArticle(graphene.Mutation):

class Arguments:
headline = graphene.String()
reporter_id = graphene.ID()
Expand Down
Loading

0 comments on commit 6945888

Please sign in to comment.