Using HarperDB With Django

using-harperdb-with-django

Before you try to use HarperDB in your Django project there are some trade offs you should consider. I wanna cover some of these first and then if you still decide HarperDB and Django are a fit, we’ll get into the “how to”.

If you’re reading this there’s a good chance you’re coming to this article as a participant of my August Code Battle Hackathon so I will write with those participants in mind.

Tradeoffs

I’ll start by saying that at this point in time HarperDB and Django are not exactly suited for each other. Many of the issues are similar to what I said in my video & article about why MongoDB and Django are not a fit, but luckily for HarperDB its in a much better position.

With MongoDB the biggest issue is that there is no database driver for Django and there hasn’t been a succesful implementation of converting Django queries into NoSQL queries. As a result of this, you lose A LOT of the features Django has built.

HarperDB has a simular issue. There is no database driver at the moment so we run into the same issue we had with MongoDB. In HarperDB’s case it’s a SQL & NoSQL distributed database so building this driver is not an impossible task. Lets hope they do it soon ๐Ÿ˜‰

Meanwhile, consider the following:

  • No more Django ORM โ€” With no database adaptor we’ll have to use the HarperDB python package instead of the Django ORM.
  • No More Admin Panel โ€” Without an adaptor we cant run the proper migrations we need.

  • Database Connection โ€” The DATABASES connection object in settings.py does nothing for us without a database driver.

  • No more migrations โ€” Cant run migrations without a database driver.
  • Authentication & Models โ€” This part I am still unsure about. If we are no longer using the Django ORM, how will authentication work with the user model? This part may have to be re-written from scratch.

My Suggestion

Use FastAPI, Flask or Custom Functions.

If you choose to use a lightweight framework you’ll have the flexibility you need to make whatever database connection you want. You could also bypass building a backend all together and try using HarperDB custom functions to build an API and connect to the database directly from your frontend.

How To Guide

Source code

I’ll assume you already have a HarperDB instance setup with a ready database and a blank Django App ready to go. If not, you can follow me in setting this up in the video tutorial for this article

1 – Install HarperDB Package

You can install the HarperDB python package here. This package will give us the tools we’ll need to connect to our database and make queries.

pip install harperdb

2 – Connect to Database

Let’s make this connection in settings.py just above the default DATABASES object.

#settings.py
import harperdb

...

DB = harperdb.HarperDB(
    url=<YOUR_HARPERDB_URL>,
    username=<YOUR_HARPERDB_USERNAME>,
    password=<YOUR_HARPERDB_PASSWORD>
)

3 – Query Database

We’ll start accessing data in our views by first importing the DB variable from settings.py and then accessing data directly.

#views.py
from django.conf import settings

db = settings.DB

def index(request):
    devs = db.search_by_value('hackathon', 'developers', "id", "*", get_attributes=['*'])
    context = {"devs":devs}
    return render(request, 'base/index.html', context)

Now to render this data in our template you would treat it like any other queryset passed through our context dictionary.

    {% for dev in devs %}
  • {{dev.name}}
  • {% endfor %}

4 – Adding CRUD

Return Single Item

def dev_profile(request, pk):
    dev = db.search_by_hash('hackathon', 'developers', [pk], get_attributes=['*'])[0]
    context = {"dev":dev}
    return render(request, 'base/profile.html', context)

Creating Items

from django.shortcuts import render, redirect

#....

def add_profile(request):
    if request.method == 'POST':
        data = request.POST
        db.insert('hackathon', 'developers', [{"name":data['name']}])
        return redirect('index')
    return render(request, 'base/form.html')

Updating Items

def update_profile(request, pk):
    if request.method == 'POST':
        data = request.POST
        db.update('hackathon', 'developers', [{"id":pk, "name":data["name"]}])
        return redirect('index')

    dev = db.search_by_hash('hackathon', 'developers', [pk], get_attributes=['*'])[0]
    return render(request, 'base/form.html', {"dev":dev})

Deleting Items

def delete_profile(request, pk):
    if request.method == 'POST':
        db.delete('hackathon', 'developers', [pk])
        return redirect('index')

    dev = db.search_by_hash('hackathon', 'developers', [pk], get_attributes=['*'])[0]
    return render(request, 'base/delete.html', {'dev':dev})

And thats it for the demo!

Total
14
Shares
Leave a Reply

Your email address will not be published. Required fields are marked *

Previous Post
hosting-azure-devops-pipelines-agents-on-github-codespaces

Hosting Azure DevOps Pipelines agents on GitHub Codespaces

Next Post
the-concept

The Concept

Related Posts