Skip to main content

dict2sql, the missing SQL API

dict2sql gives you the ability to express SQL as python data structures.

pypi badge

A simple example

from dict2sql.types import SelectStatement
from dict2sql import dict2sql

query: SelectStatement = {
    "Select": ["name", "height", "country"],
    "From": ["mountains"],
    "Where": {
        "Op": "AND",
        "Predicates": [
            {"Op": ">=", "Sx": "height", "Dx": "3000"},
            {"Op": "=", "Sx": "has_glacier", "Dx": "true"}
        ],
    },
    "Limit": 3
}

dict2sql = dict2sql()

print(dict2sql.to_sql(query))

produces

SELECT `name` , `height` , `country`
FROM `mountains`
WHERE ( ( height >= 3000 ) AND ( has_glacier = true ) )
LIMIT 3

Installing

$ pip install -U dict2sql

Notes

Rationale

For historical reasons in the world of relational databases interfaces usually consist of domain-specific languages (mostly dialects of SQL) rather than composition of data structures as it is common with modern APIs (for example JSON-based REST, protobuf). While a domain-specific language (DSL) is very well suited for interactive use, such as manually exploring a dataset, this approach has some limitations when trying to interface with a database programmatically (for example from a Python script).

This library brings a modern API to SQL databases, allowing the user to express queries as composition of basic python data structures: dicts, lists, strings, ints, floats and booleans.

Among the primary benefits of this approach is a superior ability to reuse code. All the usual python constructs and software engineering best practices are available to the query author to express queries using clean, maintainable code.

Query-as-data also means compatibility with Python's type hinting system, which translates to reduced query-correctness issues, improved error messages (at least with respect to some query engines), and a quicker development experience.

Notably, this solution eliminates one major source of friction with traditional programming-language level handling of SQL: SQL injection and excaping. While solutions to this problem such as parametrized queries have been developed over time, they heavily favor safety at the expense of expressivity; it is usually forbidden to compose parametrized queries at runtime. How is this accomplished? By having granular information about each component of a query, dict2sql is easily able to apply escaping where needed, resulting in safe queries.

Finally, it should be noted that this library strictly tries to do one job well, namely composing sql queries. There is many related functionalities in this space which we explicitely avoid taking on, feeling that they are best left to other very mature libraries in the Python ecosystem. For example: connecting to the database and performing queries, parsing query return values.

  • code reuse
  • types
  • small concern, only translating to sql
  • safety

Implementation details

This project at the moment targets ANSI SQL, with the ambition of soon targeting all major SQL dialects.

Tests are based on the Chinhook Database.

Contributing

Contributions and forks are welcome!

If you want to increment the current language to increase coverage of ANSI SQL, go right ahead.

If you plan to contribute major features such as support for a new dialect, it is recommended to start a PR early on in the development process to prevent duplicate work and ensure that it will be possible to merge the PR without any hiccups.

In any case, thank you for your contribution!

TODOs

  • actually implement sanitization/escaping (atm there's none)
  • handle different dialects
    • sqlite
    • mysql
    • postgres
  • implement tests
    • unit tests
      • compiler to ir
      • ir to sql
      • types (expressivity)
      • utils
    • integration tests
      • sqlite
    • security
      • test for sql injection
        • fuzzing
        • generative testing
  • sql functionality
    • having
    • functions
    • aggregate
    • statements
      • insert
      • delete
      • update
      • create
  • more examples
    • query end to end with sqlalchemy
    • generative examples
  • also provide types for data?
    • probably not a worthwile direction

Metadata

Release files for dict2sql 1.2.0

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

Source distribution (sdist)

Source distribution for dict2sql 1.2.0
File Size Uploaded
dict2sql-1.2.0.tar.gz 392.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for dict2sql 1.2.0
File Interpreter ABI Platform
dict2sql-1.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 788.7 kB

Release files / dict2sql-1.2.0.tar.gz

Download URL dict2sql-1.2.0.tar.gz
Size 392.8 kB
Tags Source
SHA-256 checksum
How to use checksums
8c8fd62d91c1cb3d444f62d23fcb7ff8498b72a061cb0c0b25c40dbc4eca5442
BLAKE2b-256 checksum
How to use checksums
843616cbfb339b1c84bfeec3b4cb96ded61933c529a9bc988faf905bf6e04b45
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/1.1.6 CPython/3.9.5 Linux/5.4.0-1047-azure

Release files / dict2sql-1.2.0-py3-none-any.whl

Download URL dict2sql-1.2.0-py3-none-any.whl
Size 395.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
bba47505665398775762bcdcc2e04e286045f037df46c5b886bf387b198b3d84
BLAKE2b-256 checksum
How to use checksums
ce1bc2a05ea384b484cafd76463007fee116c1e45d3814e688127aa3ff85ef12
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/1.1.6 CPython/3.9.5 Linux/5.4.0-1047-azure

Release history Release notifications | RSS feed

2.1.0

2 release files

2.0.0

2 release files

This release

1.2.0 This release

2 release files

1.1.0

2 release files

1.0.0

2 release files

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