reobject

for the Django-obsessed

Anirudha Bose
Software Engineer @ Legalstart
, Paris
https://github.com/onyb

July 2018 @ EuroPython 2018, Edinburgh

Follow this presentation here: https://slides.com/onyb/reobject-ep18

This was me, after learning Django ORM

The Django ORM

from django.db import models


class Book(models.Model):
    title = models.CharField(max_length=200)
    price = models.IntegerField()


>>> Book.objects.create(title='The C Programming Language', price=52)
>>> Book.objects.create(title='The Go Programming Language', price=30)

# All books
>>> Book.objects.all()

# Title of books under £50
>>> Book.objects.filter(price__lt=50).values('title')

Enter reobject

an ORM layer for Python objects

The reobject ORM

from reobject.models import Model, Field


class Book(Model):
    title = Field()
    authors = Field()
    price = Field()

>>> # Create a bunch of objects
>>> Book(title='The C Programming Language',
         authors=['Kernighan', 'Ritchie'], price=52)
>>> Book(title='The Go Programming Language',
         authors=['Donovan', 'Kernighan'], price=30)


>>> Book.objects.all()  # All books
[Book(title='The C Programming Language', authors=['Kernighan', 'Ritchie'], price=52),
 Book(title='The Go Programming Language', authors=['Donovan', 'Kernighan'], price=30)]

# Title of books under $50
>>> Book.objects.filter(price__lt=50).values('title')
[{'title': 'The Go Programming Language'}, {'title': 'The C Programming Language'}]

# Title of books co-authored by Brian Kernighan
>>> Book.objects.filter(authors__contains='Kernighan').values_list('title', flat=True)
['The Go Programming Language', 'The C Programming Language']

When reobject might be useful

  • Extreme code refactoring
  • Obsession with Django
  • Design patterns (contd...)

Inventing Design Patterns

from reobject.models import Model, Field


class Card(Model):
    suit = Field()
    color = Field()


>>> c1, _ = Card.objects.get_or_create(suit='K', color='♥')
>>> c2, _ = Card.objects.get_or_create(suit='K', color='♥')
>>> c3, _ = Card.objects.get_or_create(suit='A', color='♠')

>>> assert c1 is c2

Transactions

from reobject import transactional
from reobject.models import Model, Field

class Number(Model):
    value = Field()

    @transactional
    def kaboom(self):
        self.value = '1111'  # invalid value
        self.value += 1      # should rollback


num = Number(value=7)
try:
    num.kaboom()
except:
    assert num.value == 7    # Mutation to '1111' rolled back

Features

  • Elegant data-model syntax inspired by Django ORM.
     
  • Class-level model fields, out of the box object protocols, pretty reprs.
     
  • Advanced query language and chainable querysets.
     
  • Transactions.
     
  • Many-to-one model relationships.
     
  • No support for Python < 3.
     
  • 97% code coverage.
     
  • Docs; examples; TravisCI integration; pip installable.

Thank you!

reobject-ep18

By Anirudha Bose

reobject-ep18

EuroPython 2018 @ Edinburgh

  • 447