Skip to main content

Que: SQL for Sneks 🐍

Project description

Que: SQL for Sneks 🐍

image image image image image codecov

Que allows you to get generate your SQL queries on the fly, without the overhead of a fully-fledged ORM.

Motivations

Que was born out of a need for dynamically generated SQL for an ASGI web service. I found my self wishing for the convenience of dynamic querying with an ORM such as SQLAlchemy, but the performance of a fully asynchronous database client. Que attempts to fill this void. Choose the connection client you prefer and let Que worry about the SQL.

What Is It?

Que looks to solve a single purpose: generate SQL-compliant queries in pure-Python. Que has absolutely no hard dependendencies and does not enforce the use of a specific database client or dialect.

Still want to use SQLAlchemy for your connection? Go for it. Want to use PyMySQL or psycopg2? Que won't stop you. Want to use an asyncio framework such as aiopg? You have excellent taste! This library was written just for you.

Design

The focus of Que is simplicity, just look at what it takes for a simple SELECT:

>>> import que
>>> select = que.Select(table='foo')
>>> select
Select(table='foo', schema=None, filters=FilterList([]), fields=FieldList([]))
>>> sql, args = select.to_sql()
>>> print(sql)
SELECT
  *
FROM
  foo

Que works with the DBAPI client of your choice by parametrizing your sql and formatting your arguments for you:

>>> import que
>>> fields = [que.Field('bar')]
>>> filters = [que.Filter(que.Field('id', 1))]
>>> select = que.Select(table='foo', filters=filters, fields=fields)
>>> sql, args = select.to_sql()
>>> print(sql)
SELECT
  bar
FROM
  foo
WHERE
  id = :1

>>> args
[1]
>>> sql, args = select.to_sql(style=que.NameParamStyle.NAME)
>>> print(sql)
SELECT
  bar
FROM
  foo
WHERE
  id = :id

>>> args
{'id': 1}

Que works to normalize the API for your SQL operations, so that initializing an INSERT or UPDATE is functionally the same as initializing a SELECT:

>>> import que
>>> import dataclasses
>>> import datetime
>>>
>>> @dataclasses.dataclass
... class Foo:
...     bar: str
...     id: int = None
...     created: datetime.datetime = None
... 
>>> new_foo = Foo('blah')
>>> fields = que.data_to_fields(new_foo, exclude=None)
>>> insert = que.Insert(table='foo', fields=fields)
>>> sql, args = insert.to_sql(que.NameParamStyle.NAME)
>>> print(sql)
INSERT INTO
  foo (:colbar)
VALUES
  (:valbar)

>>> args
{'colbar': 'bar', 'valbar': 'blah'}

QuickStart

Que has no dependencies and is exceptionally light-weight (currently only ~30Kb!), comprising of only a few hundred lines of code. Installation is as simple as pip3 install que-py.

Then you're good to go! import que and rock on 🤘

Examples

A simple client for generating your SQL and inserting new entries:

import dataclasses
import sqlite3

import que

@dataclasses.dataclass
class Spam:
    flavor: str
    id: int = None
    created_on: int = None


class SpamClient:
    """A database client for tracking spam flavors."""

    def __init__(self):
        self.conn = sqlite3.connect('sqlite://spam.db')

    def insert_spam(self, spam: Spam):
        fields = que.data_to_fields(spam, exclude=None)
        insert = que.Insert('spam', fields=fields)
        sql, args = insert.to_sql()
        return self.conn.execute(sql, args)

    def get_spam(self, **kwargs):
        fields = que.data_to_fields(kwargs)
        filters = [que.Filter(x) for x in fields]
        select = que.Select('spam', filters=filters)
        return self.conn.execute(*select.to_sql())

    def update_spam(self, spam: Spam):
        fields = [que.Field('flavor', spam.flavor)]
        filters = [que.Filter(que.Field('id', spam.id))]
        update = que.Update('spam', filters=filters, fields=fields)
        return self.conn.execute(*update.to_sql())

    def delete_spam(self, spam: Spam):
        filters = [que.Filter(que.Field('id', spam.id))]
        delete = que.Delete('spam', filters=filters)
        return self.conn.execute(*delete.to_sql())

Documentation

Full documentation coming soon!

Happy Querying 🐍

How to Contribute

  1. Check for open issues or open a fresh issue to start a discussion around a feature idea or a bug.
  2. Create a branch on Github for your issue or fork the repository on GitHub to start making your changes to the master branch.
  3. Write a test which shows that the bug was fixed or that the feature works as expected.
  4. Send a pull request and bug the maintainer until it gets merged and published. :)

Project details


Download files

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

Source Distribution

que-py-1.1.0.tar.gz (12.4 kB view details)

Uploaded Source

Built Distribution

que_py-1.1.0-py2.py3-none-any.whl (10.7 kB view details)

Uploaded Python 2 Python 3

File details

Details for the file que-py-1.1.0.tar.gz.

File metadata

  • Download URL: que-py-1.1.0.tar.gz
  • Upload date:
  • Size: 12.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.13.0 pkginfo/1.5.0.1 requests/2.21.0 setuptools/39.1.0 requests-toolbelt/0.9.1 tqdm/4.31.1 CPython/3.7.3

File hashes

Hashes for que-py-1.1.0.tar.gz
Algorithm Hash digest
SHA256 db201ef8cd651182b625751c7065ce4074fa6e18490ed2582faff818aaae7fac
MD5 289e295476ce1a9c906c61dc531fc5d7
BLAKE2b-256 691056d9f81af1d98f1d02055c5fa2969c8579d8eeb82d347a13363d75f83031

See more details on using hashes here.

File details

Details for the file que_py-1.1.0-py2.py3-none-any.whl.

File metadata

  • Download URL: que_py-1.1.0-py2.py3-none-any.whl
  • Upload date:
  • Size: 10.7 kB
  • Tags: Python 2, Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.13.0 pkginfo/1.5.0.1 requests/2.21.0 setuptools/39.1.0 requests-toolbelt/0.9.1 tqdm/4.31.1 CPython/3.7.3

File hashes

Hashes for que_py-1.1.0-py2.py3-none-any.whl
Algorithm Hash digest
SHA256 1795840133bd5ff18fadf541a2e627c98aa01443cb0a27c70d923800309a9603
MD5 882071a70b92ae7af59495ece3129cb2
BLAKE2b-256 0140e3e1a086a014a2fb9476e6fc107d145a0fd0e8e6fc8cf76c29c144012a42

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page