Introduction
Resync is a Django-ORM inspired wrapper around the official rethinkdb driver's (currently undocumented) asyncio connection class.
Usage Examples
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