Custom python-graphene SQLAlchemy queries: Advanced use cases
I have been using the GraphQL server component python-graphene extensively over the last couple of month. While the available tutorials are easy to follow and cover some very generic use cases, it gives the impression, that Graphene is quite opinionated. To my surprise it is however not, but is in fact quite easy to adapt to more special use-cases.
These use cases, are however not documented and therefore I will discuss them here. This should then give the reader an impression, what is possible and it what direction to go for own implementations. Here we assume that you are familiar with the Graphene SQLAlchemy Tutorial and v2 of Graphene is beeing used.
Assume we have a SQLAlchemy model called User. An User shall then have a Configuration, which is however not retrieved directly through the Graphene-SQLAlchemy binding but has to be created outside the database, maybe in some more complicated way. A GraphQL Query of User and its Configuration shall give the following result:
First of all we will create the Query object that will answer by providing the User object. If you have followed the Graphene-SQLAlchemy tutorial, this should look familiar:
Note the function SQLAlchemyQuery (which you will have to implement yourself) will return the actual database row identified by the User’s id. Next we need to will implement the User GraphQL Object using the Graphene-SQLAlchemy binding and a predefined SQLAlchemy UserModel from models.py:
This would give us the above query result, but still without the possiblity to get to the Configuration of User. Therefore we will create a Configuration definition with the two field enabled and value:
Now comes the imporant step: we will connect our Configuration object with User:
get_user_configuration is a function what will retrieve the relevation configuration data (which you will have to implement yourself). The configuration.id can be a internal identifier like i.e. an integer and will automatically be converted to a corresponding GraphQL ID (QXVkaWVuY2VDb25maWd1cmF0aW9uOjQ=) by the relay.node interface. We then need to include the field definition and the resolver function directly in our User Object definition and that’s it.
This has been a more advanced use case for python-graphene and the SQLAlchemy binding that shown how you can deal with more specific demands where you have to create an object dynamically.
As always, please let me know if you have any questions of comments.