Source

djsqlalchemy / README

Full commit
============
Installation
============

::

    pip install djsqlalchemy

=====
Usage
=====

Your models.py can look like this::

    from django.db import models

    from djsqlalchemy.api import DjSqlAlchemyManager
    from djsqlalchemy.api import ManagerPlaceholder


    class ComplexQueryManager(DjSqlAlchemyManager):
        def get_select(self):
            item = self.tables['djsqlalchemy_item']
            category2 = self.tables['djsqlalchemy_category'].alias('category2')
            return (item.select(use_labels=True).column(category2)
                        .select_from(item.join(category2,
                                               category2.c.id == item.c.category2_id)))


    class Category(models.Model):
        name = models.CharField(max_length=32)

        def __unicode__(self):
            return '%s - %s' % (self.pk, self.name)


    class Item(models.Model):
        name = models.CharField(max_length=32)
        category1 = models.ForeignKey(Category, null=True, related_name='+')
        category2 = models.ForeignKey(Category, null=True, related_name='+')
        category3 = models.OneToOneField(Category, null=True, related_name='+')

        objects = models.Manager()
        complex_query = ManagerPlaceholder(ComplexQueryManager)

        def __unicode__(self):
            return '%s - %s' % (self.pk, self.name)

In your views.py you can use new manager `complex_query` (it implements Django-like API, but it's not real manager), which uses SqlAlchemy Core to build complex queries::

    sample_category = Category.objects.create(name='sample category')
    sample_item = Item.objects.create(name='sample item',
                                      category2=sample_category)

    item = Item.complex_query.get()
    assert item == sample_item
    assert item._category2_cache == sample_category

======================
Implementation details
======================

- SqlAlchemy uses Django connection. Implemented using custom pool: `djsqlalchemy.alchemy.DjangoPool`.
- Mapper uses fields names in it's work. You have to use SqlAlchemy `alias()` and `use_labels=True`.