resync-orm 0.2.2
An ORM-like wrapper for the rethinkdb asyncio driver
License: BSD 3-clause
Keywords: rethink rethinkdb asyncio

## Introduction

Resync is a Django-ORM inspired wrapper around the official rethinkdb driver's (currently undocumented) asyncio connection class.

### Usage Examples

```python
import asyncio
import resync
from resync import fields
from resync.models import Model, NestedDocument

from myapp.auth.models import User


class Grommet(NestedDocument):
    """
    Nested documents don't have a table associated, but allow you to define a
    schema for arbitrary json sub-documents in a model.
    """
    weight = fields.FloatField()
    enabled = fields.BooleanField(default=False)


class Widget(Model):
    """
    Model classes refer to a table in the database.  By default, the table
    name is the lowercased name of the class.
    """

    id = fields.StrField()
    grommet = fields.NestedDocumentField(Grommet)
    foo = fields.StrField()
    owner = fields.ForeignKeyField(User)


async def create_widget(user: User) -> None:
    """
    Model objects can be created and manipulated like ordinary python objects,
    then saved to the database.
    """
    new_widget = Widget(owner=user, foo='bar')
    new_widget.grommet = Grommet(weight=15.0)
    await new_widget.save()
    print(new_widget.id)  # '45226082-976e-4226-b2c7-0d2c86c45b73': generated by rethinkdb


async def get_widget_by_id(id: str) -> Widget:
    """
    Use the 'objects' class attribute to query the database to retrieve an
    instance.
    """
    widget = await Widget.objects.get(id=id)
    return widget


async def get_all_widgets() -> typings.List[Widget]:
    """
    Querysets can be `await`ed to get all the results in a list ...
    """
    widgets = await Widget.objects.all()
    return widgets


async def send_all_widgets_to_socket(socket: aiohttp.web.WebSocketResponse) -> None:
    """
    ... or iterated over using `async for`
    """
    async for widget in Widget.objects.all():
        serializer = MyWidgetSerializer(widget)
        socket.send(serializer.data)


async def rename_all_widgets() -> None:
    """
    Make simple changes to the database in a single query without extracting
    the objects to python code.
    """
    await Widget.objects.all().update(foo='baz')


async def get_enabled_widgets_for_user(user: User) -> typings.List[Widget]:
    """
    Querying related fields works similarly to django, returning a queryset
    that can be manipulated as normal
    """
    ret = []
    async for widget in user.widget_set.filter(enabled=True):
        ret.append(widget)
    return ret


def main():
    """
    Resync deals transparently with connections, managing a connection pool to
    reuse open connections when available.
    """
    resync.setup({
        'host': 'my.rethinkdb.fqdn',
        'db': 'my_database_name',
        'user': 'test',
        'password': '123456'
    })  # These arguments are passed to rethinkdb.connect
        # (docs: https://www.rethinkdb.com/api/python/connect/)

    loop = asyncio.get_event_loop()
    fut = asyncio.ensure_future(get_all_widgets())
    loop.run_until_complete(fut)
    print(fut.result())  # List of widgets...

    teardown = asyncio.ensure_future(resync.teardown())
    loop.run_until_complete(teardown)  # Closes all connections.
    loop.close()
```

### TODO

- Tests
- Docs

### Contributors

- James Keys (author) <@skolsuper>