GraphQL for the Beginner Pythonistas
By: Vasileios Anagnostopoulos
Tags: Flask, GraphQL

Dealing with the database

As a first step we port the init-db script from the original Flask tutorial to SQLAlchemy Orm. We will use the orm objects (DAO) in order to keep our application OO as much as possible. The script is used through CLI to initialize the database as a click application. The concepts we use could be found here for example. If you are new to SQL Alchemy ORM, stop now and come back after reading that article.

Since we use the ORM, the first step is to create an engine instead of the DB of the original tutorial. Through the engine we will create sessions to CRUD objects in the database. Take a close look on the context manager. What is this yield doing there? The first function is used because I use sqlite and the foreign key support is not on by default. I had to consult the documentation

The next modification is the initialization. We throw away any SQL scripts. In a typical database we use migrations to populate the database. Here we keep things simple. We inline the objects. But in reality the objects could live in a serialization format outside our application. E.g. JSON is the first thing that comes to mind. To this end, we need to describe the objects that mediate the actions to the database and allow the LUW pattern.

!Warning! In order to get the cascaded delete right, after some fighting, I had to consult this excellent explanation:

Now we have all the facilities to initialize our database.

The easy part is done. We proceed to model the CRUD actions with GraphQL.

GraphQL modelling

To follow the discussion keep in a separate tab the excellent GraphQL tutorial. Now that we have objects to model what goes in and out to our database as an object repository we need to make the corresponding objects that specify the types our GraphQL works with. We also provide conversion functions that translate from ORM land to GraphQL land. The GraphQL objects are prefixed with GQL.

The convert functions just take a DAO object and transform it to a GraphQL object. The interesting part here is that the object fields are initialized with objects that specifiy the schema types. So a string field is initialized to a graphene.String object. the same holds for Int fields. An object field is initialized with a graphene.Field object that its constructor takes as parameter the class of the GraphQL object. There are many common types that users should utilize but these are the principles.

The first GraphQL query

We proceed to create our Query, the R part of CRUD. We aim to be able to query all users, all posts (this is why we initialized the database with sample objects) , a particular user by username or a post by title. We need to create a container object, called Query that carries all these queries. All of them actually.

Everytime we ask one of them (or more than one) and since the rest are not used they do not participate in the result formation process. The query is resolved by the server that acts as a “database” and can assemble the object by retrieving its parts from various databases, from REST services or even by polling a peripheral port of the computer. In this post we focus in assembling our resolution from the database. We just make calls through SQLAlchemy to the database to retrieve objects.

Executing queries interactively

Let us see how it looks. We run the application according to the README.md in the repository. Navigating to http://127.0.0.1:5000/graphql we arrive at a beautiful prompt installed by the GraphiQL package. It is actually an interactive prompt for executing GraphQL statements. We also have implemented some mutations. For now let’s focus on the Query part.

Click on it. On the left panel we can enter our query. On the rightmost panel we view all the possible subqueries nicely typed. Lets harvest the power of Graphql. Our first query amounts to viewing what we have inserted to the database by default for the posts. See the next gist.

We can just describe what we expect from every post. It is like minimal SQL. While you type the gist, look how nicely it does autocompletion based on our small CRUD universe of types.

After executing it we see that it brings us what we asked. Nothing more, nothing less.

Feel free to experiment by exploring the interactive repl and reading the Graphql documentation.

Mutation time

We did not implement all the possible mutations. But it is a good exercise to implement the U part of the CRUD gang. Here is the C & D mutations we created.

We will create a post for an existing user. Pay attention to the Arguments class that is a placeholder for arguments, that they will be propagated to the mutate action. The mutation action returns something. Here we return the whole post object. Again, I should notice that the official documentation is a prerequisite for mutations. But one can use only the id part. A picture is worth a thousand words . Take a close look at the south west “Query Variables” tab that appears on pressing.

through the gist

Another more direct way is shown here

through the gist

By executing our mutation we got back the whole post. Run again the allposts query we previously mentioned in order to see the new insertion.