Introduction to serverless databases with faunadb and python

Introduction to serverless databases with faunadb and python

INTRODUCTION

In recent years, serverless computing has gained popularity as a way to build applications faster and more efficiently. One of the key components of serverless architecture is serverless databases, which eliminate the need for database servers and provide scalability and flexibility to handle fluctuating workloads. FaunaDB is a serverless NoSQL database that allows you to build modern applications without worrying about database infrastructure management. In this article, we'll explore the basics of FaunaDB and how to use it with Python to create serverless applications by building a contact manager.

What is a serverless database?

A serverless database is a database that does not require any server infrastructure to manage or operate. Instead, it provides a cloud-based environment that automatically manages scalability, availability, and other operational tasks.

What is FaunaDB?

FaunaDB is a serverless NoSQL database that enables you to build applications with global scalability and high performance. It's designed to be developer-friendly, and it provides a flexible data model that allows you to store structured, semi-structured, and unstructured data.

Why use FaunaDB?

  • Serverless architecture: FaunaDB eliminates the need for database servers and provides automatic scaling, so you don't have to worry about infrastructure management.

  • Global distribution: FaunaDB is built on a globally distributed architecture, which means your data is always available and accessible from anywhere in the world.

  • Developer-friendly: FaunaDB provides a rich set of APIs and SDKs for various programming languages, making it easy to integrate with your application.

  • Flexible data model: FaunaDB supports a flexible data model that allows you to store structured, semi-structured, and unstructured data, making it suitable for a wide range of use cases.

Let's get started!

Step 1: Install required libraries

To get started, we'll need to install the required libraries. We'll be using the FaunaDB Python driver, Flask, and the dotenv library to load environment variables. You can install them using pip: pip install faunadb flask python-dotenv. After that we will clone this github repo:https://github.com/feranmiodugbemi/ContactManager/tree/5d7d969a3ef23bb3cd81fb5b8f41e2b04883e4ba. Then, we will create a .env and a .gitignore file in our root directory. We should have something like this in our directory:

directory image

Though this is an updated code but our UI should look something like this after we run python app.py at http://localhost:5000/:

UI image

Step 2: Creating our database

To create our database watch this video below:

Our database should be named "Contactmanager" and should not be prepopulated with demo data

Step 3: Creating our Collection

A collection is simply a grouping of related data or documents within a database. To create our Collection watch this video below:

Our Collection should be named "Users".

Step 4: Getting our FaunaDB access key

Next, you need to set up your database access key. You can get your access key by creating an account on FaunaDB's website and then create a new database. Watch this video if you don't know how to get your "access key":

Then we store our "access key" in our .env file in a FAUNASECRET variable.

Step 5: Updating our UI

Bceause I will not be going into details about the UI. Delete everything in the index.html file and replace it with the HTML in this link: https://github.com/feranmiodugbemi/ContactManager/blob/master/templates/index.html

Step 6: Setting up our flask application

First, let's create a new Flask application and import the necessary libraries. We'll be using the faunadb library to interact with FaunaDB, and dotenv to load environment variables.

from flask import Flask, render_template, request, flash, redirect
from faunadb import query as q
from faunadb.objects import Ref
from faunadb.client import FaunaClient
from dotenv import load_dotenv
import os

load_dotenv()
app = Flask(__name__)
app.config["SECRET_KEY"]='Feranmiodugbemi'

Also, you can name your app.config whatever you like. We also need to connect to FaunaDB. To do this, we'll create a new instance of FaunaClient and pass in our FaunaDB secret key, which we'll store in an environment variable.

client = FaunaClient(
  secret=os.getenv('FAUNASECRET')
)

Step 7: Creating a new contact

Now that we have our Flask application set up and connected to FaunaDB, we can create the functionality to create, update, and delete contacts.

Let's start with creating a new contact. We'll define a new route and add a form to our HTML template to collect the necessary information.

@app.route("/", methods=["POST", "GET"])
def hello():
    if request.method == "POST":
        name = request.form.get('name')
        occupation = request.form.get('occupation', default='')
        address = request.form.get('address', default='')
        contact = request.form.get('contact')
        email = request.form.get('email', default='')
        client.query(
            q.create(
                q.ref('collections/Users'),
                {
                    'data':{
                        'id': q.new_id(),
                        'name':name,
                        'occupation':occupation,
                        'address' : address,
                        'contact': contact,
                        'email': email
                    }
                }
            )
        )
        flash("New contact added successfully", category="success")
        return redirect('/')
    else:
        return render_template('index.html')

In this code, we're using the request object to retrieve the data from the form. We're then using the create function from the query module of faunadb to create a new contact in our FaunaDB database. The create function takes two arguments: the collection where we want to add the new contact, and the data we want to add.

We're also using the flash function to display a success message to the user, and then redirecting them back to the homepage.

Step 8: Getting all the contacts

Next, let's add the functionality to get all the contacts from our FaunaDB database and display them on the homepage. We'll define a new route and use the paginate function from the query module to retrieve all the documents in our collection and store them in a list called data. We then pass this list to the index.html template as a parameter to display the data.

# Getting all the contacts
result = client.query(
    q.map_(
        q.lambda_("x", q.get(q.var("x"))),
        q.paginate(q.documents(q.collection("Users")))
    )
)
data = [doc["data"] for doc in result["data"]]
return render_template('index.html', data=data)

We will replace the code in the else statement with the code above.

Step 9: Creating our index

Incase you're wondering what an index is🤔, an Index is a data structure that improves the speed of data retrieval operations on a database table. It is essentially a list of values that are organized in a specific order to facilitate faster search and retrieval of data.

An index is created on one or more columns of a database table, and it can be used to quickly locate rows of data based on the values in those columns. By creating an index, database queries can be optimized, resulting in faster response times and improved performance and FaunaDB make it very easy to create an index. You can create an index by following this video below:

Our index should be named "users_by_id"

Step 10: Adding our Delete Functionality

The delete functionality is implemented in the delete route. This route takes an id parameter that is used to select the document to be deleted from the collection using the index. We first convert the id parameter to a string, then use it to search for the document in the collection using a match query. We then use the select query to retrieve the document reference and use it to delete the document.

@app.route('/delete/<int:id>')
def delete(id):
    id = str(id)
    result = client.query(
        q.select(['ref'], q.get(q.match(q.index("users_by_id"), id)))
    )
    client.query(q.delete(result))
    return redirect('/')

Step 11: Adding our Update Functionality

The update functionality is implemented in the update route. This route takes an id parameter that is used to select the document to be updated from the collection using the index. We first convert the id parameter to a string, then use it to search for the document in the collection using a match query. We then use the select query to retrieve the document reference and use it to update the document.

@app.route('/update/<int:id>', methods=["POST"])
def update(id):
    id = str(id)
    if request.method == "POST":
        name = request.form.get('updatename')
        occupation = request.form.get('updateoccupation', default='')
        address = request.form.get('updateaddress', default='')
        contact = request.form.get('updatecontact')
        email = request.form.get('updateemail', default='')
        result = client.query(
            q.select(['ref'], q.get(q.match(q.index("users_by_id"), id)))
        )
        client.query(
            q.update(result, {
                'data':{
                    'name': name,
                    'occupation': occupation,
                    'address': address,
                    'contact': contact,
                    'email': email
                }
            })
        )
    return redirect('/')

Conclusion

In this article, we have shown how to use FaunaDB with Python Flask to create a simple CRUD application. We have provided explanations and additional information for each functionality implemented in the application. We hope that this article has helped introduce FaunaDB and demonstrate its use in a practical application. You can get the full code to the github repo here: https://github.com/feranmiodugbemi/ContactManager. If you have any questions, don't hesitate to contact me on Twitter: @FeranmiOdugbemi