Skip to main content

An alternative Django query language

Project description

copyright (c) Paul Wolf

To Install:

git clone
cd djaq

Create the virtualenv:

virtualenv -p python3 .venv

Activate the virtual environment:

source ../.venv/bin/activate

The module itself does not install Django and there are no further requirements. The example Django application is in ./bookshop. To install dependencies for the sample application:

cd bookshop
pip install -r requirements.txt

Make sure the virtualenv is activated! The sample database is already part of source code now (sqlite). The example application comes with a management command to run queries:

./ djaq "(, max(Book.price) - round(avg(Book.price)) as diff) Book b"  --format json

If using in code, you would do this:

from xquery.exp import XQuery as XQ
xq = XQ("(avg(b.price) as average_book_price) Book b"

There are several generators to choose from to iterate records:

XQuery.json()  # return json objects
XQuery.dicts() # dicts
XQuery.tuples() # tuples of values
XQuery.objs()  # We return for each record, an instance of XQueryInstance

The XQueryInstance is basically a namespace so you can do this:

for inst in XQ('(, Book.price)').objs():


Output of the command should look like this:

▶ ./ djaq "(, max(Book.price) - round(avg(Book.price)) as diff) Book b"  --format json
SELECT, (max(books_book.price) - round(avg(books_book.price))) FROM books_book LEFT JOIN books_publisher ON (books_book.publisher_id =  GROUP BY LIMIT 10
{"publisher_name": "Avila, Garza and Ward", "diff": 14.0}
{"publisher_name": "Boyer-Clements", "diff": 16.0}
{"publisher_name": "Clark, Garza and York", "diff": 15.0}
{"publisher_name": "Clarke PLC", "diff": 14.0}
{"publisher_name": "Griffin-Blake", "diff": 16.0}
{"publisher_name": "Hampton-Davis", "diff": 13.0}
{"publisher_name": "Jones LLC", "diff": 15.0}
{"publisher_name": "Lane-Kim", "diff": 15.0}
{"publisher_name": "Norris-Bennett", "diff": 14.0}
{"publisher_name": "Singleton-King", "diff": 17.0}

Notice the SQL used to retrieve data is printed first.

The syntax is like this:

<join_operator> (<column_exp>, ... ) ModelName{<filter_expression>} Alias

Most of these are optional. You don’t have to reference models in an expression with Alias; you don’t need a filter in curly braces, etc. There is no point in providing the join_operator on the first relation. You can have as many of these as you wish to add more relations. You can even skip the join relation on subsequent relations: it will default to LEFT JOIN. Don’t bother doing this:

(, Book -> Publisher

because you can just do this:

(, Book

It will know to create the join to Publisher. But you might want to include it for the purpose of having an alias for Publisher:

(, Book b -> Publisher p

Use “as” operator to name columns:

( as book_name, as publisher) Book b -> Publisher p

Get the average price of books for each publisher:

(avg(b.price)) Book b

Get the difference off the maximum price:

(, max(Book.price) - avg(Book.price) as diff) Book b

Count books per publisher:

(, count( as num_books) Book b

Count books with ratings up to and over 3:

(sum(b.rating > 3), sum(b.rating <= 3)) Book b

Get average, maximum, minimum price of books:

(avg(b.price), max(b.price), min(b.price)) Book b


Project details

Release history Release notifications

This version


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Files for Djaq, version 0.0.0
Filename, size File type Python version Upload date Hashes
Filename, size Djaq-0.0.0.tar.gz (13.9 kB) File type Source Python version None Upload date Hashes View

Supported by

Pingdom Pingdom Monitoring Google Google Object Storage and Download Analytics Sentry Sentry Error logging AWS AWS Cloud computing DataDog DataDog Monitoring Fastly Fastly CDN DigiCert DigiCert EV certificate StatusPage StatusPage Status page