Skip to main content

django-raw-sugar

Turns your raw sql into a QuerySet.

Installation

Install using pip...

pip install django-raw-sugar

How to use

Basic usage

Attach RawManager instance to your model. Then use it's .from_raw() method.

RawManager.from_raw(raw_query=None, params=None, translations=None, null_fields=None, db_table=None)

You should provide either raw_query or db_table (but not both).

# models.py
from django.db import models
from raw_sugar import RawManager

class MySimpleModel(models.Model):
    name = models.TextField()
    number = models.IntegerField()
    source = models.ForeignKey(AnotherSimpleModel, models.DO_NOTHING)

    objects = RawManager()

# some other file
from .models import MySimpleModel

queryset = MySimpleModel.objects.from_raw(
    'SELECT Null as id, "my str" as name, 111 as number, Null as source_id')

The result of your raw sql must contain all the fields that are present in target model, including primary key and foreign keys. If you know your raw sql lacks some fields, you can provide the null_fields argument instead of modifying your query:

queryset = MySimpleModel.objects.from_raw(
    'SELECT "my str" as name, 111 as number', null_fields=['id', 'source_id'])

The resulting queryset is a regular models.QuerySet instance, and can be handled accordingly:

queryset = queryset.filter(number__gte=10)\
    .exclude(number__gte=1000)\
    .filter(name__contains='s')\
    .order_by('number')\
    .select_related('source')
print(queryset[0].name) # "my str"

Passing parameters

If you need to perform parameterized queries, you can use the params argument:

queryset = MySimpleModel.objects.from_raw(
    'SELECT "%s" as name, 111 as number', 
    params=['my str'],
    null_fields=['id', 'source_id'])

If you want to pass params deferred, you can use the with_params method:

queryset = MySimpleModel.objects.from_raw(
    'SELECT "%s" as name, 111 as number', 
    null_fields=['id', 'source_id'])
queryset = queryset.with_params('my str')

Using transtalions

If the field names of queried table differ from the model field names, you can map fields by using the translations argument:

queryset = MySimpleModel.objects.from_raw(
    'SELECT "%s" as name, 111 as inner_number', 
    params=['my str'],
    translations={'inner_number': 'number'},
    null_fields=['id', 'source_id'])

Pre defined source raw sql

You can define a model manager that uses your raw sql as query source by default. You can do this by passing a from_raw argument to RawManager, or by using the raw_manager decorator to method that returns a FromRaw instance:

from django.db import models
from raw_sugar import raw_manager, RawManager, FromRaw

class MySimpleModel(models.model):
    name = models.TextField()
    number = models.IntegerField()
    source = models.ForeignKey(AnotherSimpleModel, models.DO_NOTHING)

    my_raw_manager = RawManager(FromRaw('SELECT "my str" as name, 111 as number',
                                        null_fields=['id', 'source_id']))

    @raw_manager
    def my_raw_manager_2(cls):
        return FromRaw('SELECT "my str" as name, 111 as number',
                       null_fields=['id', 'source_id'])

    @raw_manager(is_callable=True)
    def my_callable_raw_manager(cls, name=""):
        return FromRaw('SELECT %s as name, 111 as number',
                       null_fields=['id', 'source_id'],
                       params=[name])

# some other file
from .models import MySimpleModel

queryset = MySimpleModel.my_raw_source.all()
queryset = MySimpleModel.my_raw_source_2.all()
queryset = MySimpleModel.my_callable_raw_source('my str').all()

print(queryset[0].name) # "my str"

The FromRaw class accepts all the arguments as the RawManager.from_raw: FromRaw(raw_query=None, params=None, translations=None, null_fields=None, db_table=None)

When you use the raw_manager decorator, the parameters you pass to with_params method will be passed into the decorated method, not into your raw. If you need this behavour, you can do it manually:

@raw_manager(is_callable=True)
def my_callable_raw_manager(cls, *args):
    assert len(args) == 2
    return FromRaw('SELECT %s as name, %s as number', null_fields=['id', 'source_id'], params=args)

Querying views / table functions

If you have a sql view or a sql table function in your database and want to query it, instead of passing sql like SELECT * from my_view you can use the db_table argument:

queryset = MySimpleModel.objects.from_raw(db_table='my_view')
queryset = MySimpleModel.objects.from_raw(db_table='my_func(%s, %s)', params=['param', 1])
queryset = MySimpleModel.objects.from_raw(db_table='my_func(%s, %s)').with_params('param', 1)

Use a QuerySet as a source

You can use a QuerySet instance as a source instead of raw sql by returning a FromQuerySet instance from decorated manager method:

class MySimpleModel(models.Model):
    name = models.TextField()
    number = models.IntegerField()
    source = models.ForeignKey(
        AnotherSimpleModel, models.DO_NOTHING, null=True)

    @raw_manager
    def my_qs_manager(cls):
        return FromQuerySet(
            cls.objects.values('source')\
                .annotate(_number=models.Sum('number')),
            translations={'_number': 'number'})

The FromQuerySet class accepts only a QuerySet and translations:

FromQuerySet(queryset, translations=None)

If the provided QuerySet lacks some fields, the Null will be returned. You don't need to specify null_fields as you would with the FromRaw.

Differences with Manager.raw()

Pros:

  • The result of executing of your raw sql is a QuerySet (!!!), and can filter, order, annotate, union, etc. it.

Cons:

  • The result of your FromRaw must contain all fields of target model, including primary and foreign keys. If you omit any, you get an OperationalError('no such column: ...') exception.
  • If you don't provide some fields in source QuerySet when use the FromQuerySet, this fields are filled with Null, and can not be loaded on demand. The Django's RawQuerySet allows it.

Metadata

Release files for django-raw-sugar 0.1.18

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for django-raw-sugar 0.1.18
File Size Uploaded
django-raw-sugar-0.1.18.tar.gz 7.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for django-raw-sugar 0.1.18
File Interpreter ABI Platform
django_raw_sugar-0.1.18-py3-none-any.whl Python 3 none any Details

Total release size: 16.8 kB

Release files / django-raw-sugar-0.1.18.tar.gz

Download URL django-raw-sugar-0.1.18.tar.gz
Size 7.8 kB
Tags Source
SHA-256 checksum
How to use checksums
7a06ef02a4f5fe0c92cb4360207f2e3029fad5efe5d9b392a25c9ff649eac8a8
BLAKE2b-256 checksum
How to use checksums
6422c54c79f84780dc5f728d40a1c8fe1632ba7a31a54be1f0961e08604d5cd9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/3.3.0 pkginfo/1.7.0 requests/2.22.0 setuptools/49.3.1 requests-toolbelt/0.9.1 tqdm/4.56.2 CPython/3.8.6

Release files / django_raw_sugar-0.1.18-py3-none-any.whl

Download URL django_raw_sugar-0.1.18-py3-none-any.whl
Size 9.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
457d892dbe8aead7db369ad7dabf5781de5c1895e75ba4fab2934b5d64c042f9
BLAKE2b-256 checksum
How to use checksums
a0779aad4526bc011b2726d66fd629b41459489f90ab8c83e001fd746ca1bb31
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/3.3.0 pkginfo/1.7.0 requests/2.22.0 setuptools/49.3.1 requests-toolbelt/0.9.1 tqdm/4.56.2 CPython/3.8.6

Release history Release notifications | RSS feed

This release

0.1.18 This release

2 release files

0.1.17

1 release file

0.1.16

2 release files

0.1.15

2 release files

0.1.14

2 release files

0.1.13

2 release files

0.1.12

2 release files

0.1.11

2 release files

0.1.10

1 release file

0.1.9

1 release file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page