Written in connection with the Write with Fauna program.
This article focuses on exploring Fauna’s CRUD capabilities to build a Python web application for managing debts. We will be creating a debt manager that provides functionalities for keeping track of debts users have incurred using Python and Flask.
Fauna is a flexible, developer-friendly, transactional cloud database delivered as a secure Data API that provides two interfaces: GraphQL and the Fauna Query Language (FQL). It includes functionality to store collections, indexes, and other databases (multi-tenancy). To learn more about Fauna, visit the official documentation.
Note: The rest of this article assumes you have a fair understanding of Fauna, Python, and Flask. For an in-depth tutorial on serverless databases and Fauna, check out my Fauna intro tutorial first.
Setting Up the Fauna Database
Create the Fauna Database
We need to create the database for the debt manager in Fauna’s dashboard. If you have not created an account on Fauna before now, create one on Fauna’s website.
In the dashboard, click on the NEW DATABASE button, provide a name for the database then press the SAVE button.
Create the Database Collections
Now, we need to create a Fauna collection to store data collected in the recently created database. A collection is similar to SQL tables containing similar characteristics, e.g., a user collection with information about users in the database.
To create a collection:
- navigate to the
Collectionstab on the Fauna sidebar (left side of the screen) - click on the
NEW COLLECTIONbutton - provide a name for the collection
- press the
SAVEbutton
Create the Collection Indexes
We need to create an index for the collection of the database. A Fauna index allows us to browse through data stored in a database collection based on specific attributes.
To create an index:
- move to the
Indexestab on the Fauna sidebar (left side of the screen) - click on the
NEW INDEXbutton and provide the necessary information - press the
SAVEbutton.
Generate Database Security Key
Finally, we need to create a Security Key to connect the database to the application. Go to the Security tab on the Fauna sidebar (left side of the screen), click the NEW KEY button, provide the necessary information, and then press the SAVE button.
Once you have done this, Fauna will present you with your Secret Key. Copy the key immediately and store it somewhere easily retrievable because it will only be displayed once.
Downloading the Demo Application
Clone the Project Repository
For the sake of convenience, I have written a Flask application with a Bootstrap user interface that we will use in this article. To get started, we need to clone my repository and initialize the application like so:
git clone https://github.com/LordGhostX/fauna-debt-tracker
cd fauna-debt-tracker
Install the Project Requirements
We need to install the external libraries required by the application before we can run it. In the terminal, type:
pip install -r requirements.txt
Finally, run the application to make sure it’s working. In the terminal, type:
python3 app.py
Configuring the Project Settings
To configure the project, open the app.py file and replace the FAUNA_SECRET_KEY placeholder variable with the Security Key generated earlier. You can also change the application’s SECRET KEY or fetch these values using environment variables.
Integrating Fauna into Python and Flask
For the debt manager, we will explore the four basic operations of persistent storage, Create (C), Read (R), Update (U), and Delete (D), using Fauna.
Creating New Documents in Fauna
In our add_loan route, we used Fauna’s Create function to store the collected loan data in our database’s loans collection.
@app.route("/loans/add/", methods=["POST"])
def add_loan():
name = request.form.get("name")
amount = request.form.get("amount")
date = request.form.get("date")
loan_data = client.query(
q.create(
q.collection("loans"), {
"data": {
"name": name,
"amount": float(amount),
"pending": True,
"date_created": datetime.strptime(date, "%Y-%m-%d").astimezone(tz=tz.tzlocal())
}
}
)
)
flash("You have successfully added loan information!", "success")
return redirect(url_for("loans"))
The
Createfunction adds a new document to a collection. It takes acollection_refparameter which indicates what collection we should create the document, and aparam_objectparameter which contains the document data and optional metadata.
Reading Documents from Fauna
In our loans route, we used Fauna’s Paginate function to retrieve the references of stored loans in our database, then the Get function to query the data of each document with their Reference.
@app.route("/loans/")
def loans():
loans = client.query(
q.paginate(
q.match(q.index("loans_by_pending"), True),
size=100_000
)
)
loans_data = [
q.get(
q.ref(q.collection("loans"), loan.id())
) for loan in loans["data"]
]
return render_template("loans.html", loans_data=client.query(loans_data))
Updating Documents in Fauna
In our update_loan route, we used Fauna’s Update function to update the loan amount of documents in our collection. The Update function takes a Reference parameter which indicates the document to be updated, and a param_object parameter which contains the document data to update.
@app.route("/loans/update/", methods=["POST"])
def update_loan():
action = request.form.get("action")
amount = request.form.get("amount")
loan_id = request.form.get("loanID")
loan_data = client.query(
q.get(
q.ref(q.collection("loans"), int(loan_id))
)
)
old_amount = loan_data["data"]["amount"]
if action == "Borrow More":
new_amount = old_amount + float(amount)
elif action == "Repay Loan":
new_amount = old_amount - float(amount)
client.query(
q.update(
q.ref(q.collection("loans"), int(loan_id)), {
"data": {
"amount": new_amount
}
}
)
)
flash("You have successfully updated loan information!", "success")
return redirect(url_for("loans"))
Deleting Documents from Fauna
In our clear_loan route, we used Fauna’s Delete function to delete a document from the database with a specified Reference. The Delete function removes a document. This includes user-created documents, plus system documents for Collections, Indexes, Databases, etc.
@app.route("/loans/clear/<int:loan_id>/")
def clear_loan(loan_id):
client.query(
q.delete(
q.ref(q.collection("loans"), loan_id)
)
)
flash("You have successfully cleared loan information!", "success")
return redirect(url_for("loans"))
Conclusion
In this article, we built a debt tracker with Fauna's serverless database and Python. We saw how easy it is to integrate Fauna into a Python application and got the chance to explore some of its core features and functionalities.
The source code of the debt manager is available on GitHub. If you have any questions, don't hesitate to contact me on Twitter: @LordGhostX







Top comments (0)