Pure serverless Django with django-gcloud-connectors
Tags: datastore, googlecloud, serverless, django
Published: 2020-07-07 03:28:02

Django officially supports a [number of database backends](https://docs.djangoproject.com/en/3.0/ref/databases/#databases) -- including PostgreSQL, MySQL, and SQLite -- which means you can write your Django project once and deploy it to any of these database backends. 

But, there are [third-party packages](https://docs.djangoproject.com/en/3.0/ref/databases/#using-a-3rd-party-database-backend) to support other databases, even non-relational databases like [Google Datastore](https://cloud.google.com/datastore). 

In this project, I used [django-gcloud-connectors](https://gitlab.com/potato-oss/google-cloud/django-gcloud-connectors), newly released on [pypi as a 0.1.0](https://pypi.org/project/django-gcloud-connectors/) from [Potato London](https://p.ota.to/), to make a Django deployment on Google Cloud _completely serverless_ (and in theory, free!)

Sample project code → [github.com/glasnt/mewgram](https://github.com/glasnt/mewgram)

Sample project screenshot ⤵ 
![sample screenshot](https://dev-to-uploads.s3.amazonaws.com/i/5t1alqcsgbq45wla0xoj.png)

---

I spoke at my first DjangoCon Europe back in 2016 in Budapest, where I saw an intriguing talk by [Adam Alton](https://twitter.com/altonpowers): [Building A Non-Relational Backend For The ORM](https://2016.djangocon.eu/speakers/3) ([video](https://www.elastic.co/videos/building-a-non-relational-backend-for-the-orm-by-adam-alton)). His talk centered around [djangae](https://github.com/potatolondon/djangae), which allows vanilla Django sites deployed to App Engine to use [Datastore](https://cloud.google.com/datastore/), a highly scalable NoSQL database (currently referred to as "Firestore in Datastore Mode"). 

However, djangae -- as the name suggests with the GAE at the end -- requires Google App Engine. However, I'm a containers girl and I prefer Cloud Run, so I thought, how hard could it be to use the bits of djangae just to get the database backend into Datastore working?

Turns out, it's not hard when djangae itself uses django-gcloud-connectors. 

By [installing and integrating](https://github.com/glasnt/mewgram#datastore-configurations-of-note) django-gcloud-connectors into a sufficiently simple Django app, and with some learning about how [indexes in Datastore](https://cloud.google.com/datastore/docs/concepts/indexes) work, I was able to put together a proof of concept that deploys using the Cloud Run Button onto Google Cloud Run, allowing you to deploy this sample app and see it working today. 

---

But why do you need a purpose-built backend connector?

You can use [google-cloud-datastore](https://pypi.org/project/google-cloud-datastore/) to interact directly to Datastore with Python. However, if you want to take advantage of Django's ORM, you need to use a connection that maps Django's models to that specific database. The [officially supported databases](https://docs.djangoproject.com/en/3.0/ref/databases/) are officially supported for a reason -- the eccentricities of having a generic ORM interfacing to any relational database is not easy, and keeping them up to date for popular databases is important. 

The folks at Potato have -- incredibly -- made Django (mostly) work on a non-relational database. I say mostly for a reason -- there are some limitations with Datastore itself which means some of the more complex functionality that is taken for granted in a relational database just isn't available for Datastore, and as such djangae and django-gcloud-connectors cannot support it. I came across issues where cross-join `where` filters were not supported when trying to migrate `unicodex`. Take a look at the [`NotSupportedError` exceptions in `parser/base.py`](https://gitlab.com/potato-oss/google-cloud/django-gcloud-connectors/-/blob/master/gcloudc/db/backends/datastore/parsers/base.py#L74) for more examples. 

--- 

Did you say free?

Well, yes, mostly. While you do need to have billing enabled to deploy mewgram, Datastore itself has a generous free tier, as do the other elements involved. I normally use Postgres for my Django demos, like [unicodex](https://github.com/GoogleCloudPlatform/django-demo-app-unicodex), and the smallest Cloud SQL database has a non-zero monthly cost. In theory, unless your application gets super popular, you should have no ongoing costs running a Django project backed to Datastore. As always, consider the costs involved and [setup billing alerting](https://cloud.google.com/billing/docs/how-to/budgets) for long-running projects!

---

Cats?

Yup, the [identicons](https://en.wikipedia.org/wiki/Identicon) are provided by [robohash](https://robohash.org/), a [Python package](https://github.com/e1ven/Robohash) that has a cat setting. 


---

Why connector*s*? 

The package is called django-gcloud-connector**s** -- plural -- the [project README](https://gitlab.com/potato-oss/google-cloud/django-gcloud-connectors#django-gcloud-connectors-gcloudc) currently only supports Firestore in Datastore mode, but hopes to support Firestore (in Native mode) in the future. With [Django 3.1](https://docs.djangoproject.com/en/3.1/releases/3.1/) slated to introduce even more ASGI compatibility, I look forward to hopefully one day having a full asynchronous Django, with a realtime database to boot. 

---

You can learn more about django-gcloud-connectors at [gitlab.com/potato-oss/google-cloud/django-gcloud-connectors](https://gitlab.com/potato-oss/google-cloud/django-gcloud-connectors#django-gcloud-connectors-gcloudc), and Potato London at [https://p.ota.to/](https://p.ota.to/).