django_nosql

Stream model updates to nosql backends


Install
pip install django_nosql==0.0.1

Documentation

Django NoSQL

coverage

Stream model changes to an upstream NoSQL database

Supported backends:

  • FireStore
  • Mock

Todo backends

  • RethinkDB
  • Postgres (JSONField)
  • REST
  • Redis
  • etcd

Installation

pip install django-nosql

Setup

Add to installed apps:

INSTALLED_APPS = [
    ...,
    'django_nosql',
    ...
]

Configure NoSQL backends:

In settings.py:

# you can have multiple backends:
NOSQL_BACKENDS = ['firestore']

#  FireStore settings
FIRESTORE_CREDENTIALS_FILE = '/path/to/credentials.json'

Mark up your models:

In models.py


Todo(models.model):
    # the nosql collection you'd like to use
    collection = 'todos'
    # A Django Rest Framework serializer for serializing your instance
    serializer_path = 'example_app.models.TodoSerializer'
    # inform django_nosql that you'd like to sync this model
    readonly_sync = True

Add signals:

from django_nosql.signals import (
    sync_readonly_db,
    sync_remove_readonly_db
)

Test it out:

There is an example app included in this repo.

To see the sync in action try.

python manage.py shell or docker-compose run --rm web python manage.py shell


from example_app.models import Todo
todo = Todo.objects.create(text='Setup django nosql')
# you should see this reflected in the 'todos' collection in Firebase
# note: you need to manually refresh the db view when adding a new collection
# you should see the rest of these updates in realtime

# try update:
todo.done = True
todo.save()
# you should see your change reflected in firestore

# delete it:
todo.delete()
# it's gone from Firestore!

Take it async

If you're using something like celery or django-rq, you can make your signals async by wrapping the base function in a @shared_task. e.g.:

from django.db.models.signals import post_save, post_delete
from django.dispatch import receiver
from django.conf import settings
from django_nosql.signals import (sync_readonly_db, SYNC_TYPE)
from celery import shared_task

# create a shared task that wraps `sync_readonly_db`
@shared_task
def firebase_sync(instance, created):
  sync_readonly_db(instance, SYNC_TYPE.UPDATE, created)

@shared_task
def firebase_sync_remove(instance):
  sync_readonly_db(instance, SYNC_TYPE.DELETE, False)

# call that function in a delayed manner
@receiver(post_save, dispatch_uid="django_nosql.sync")
def sync_readonly_db(sender, instance, created, **kwargs):
    firebase_sync.delay(instance, created)

@receiver(post_delete, dispatch_uid="django_nosql.sync.delete")
def sync_remove_readonly_db(sender, instance, **kwargs):
    firebase_sync_remove.delay(instance)

Contributing

Deploy to pip

# bumpversion:
bumpversion {major|minor|patch}
# push to gitlab
git push origin master
# gitlab CI does the rest