Metadata-Version: 2.1
Name: sqeleton
Version: 0.0.4
Summary: Python library for querying SQL databases
Home-page: https://github.com/datafold/sqeleton
License: MIT
Author: Erez Shinan
Author-email: erezshin@gmail.com
Requires-Python: >=3.7,<4.0
Classifier: Development Status :: 2 - Pre-Alpha
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Information Technology
Classifier: Intended Audience :: System Administrators
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Topic :: Database :: Database Engines/Servers
Classifier: Typing :: Typed
Provides-Extra: clickhouse
Provides-Extra: duckdb
Provides-Extra: mysql
Provides-Extra: oracle
Provides-Extra: postgresql
Provides-Extra: presto
Provides-Extra: snowflake
Provides-Extra: trino
Provides-Extra: tui
Provides-Extra: vertica
Requires-Dist: click (>=8.1,<9.0)
Requires-Dist: clickhouse-driver; extra == "clickhouse"
Requires-Dist: cryptography; extra == "snowflake"
Requires-Dist: dsnparse
Requires-Dist: duckdb (>=0.6.0,<0.7.0); extra == "duckdb"
Requires-Dist: mysql-connector-python (==8.0.29); extra == "mysql"
Requires-Dist: presto-python-client; extra == "presto"
Requires-Dist: psycopg2; extra == "postgresql"
Requires-Dist: rich
Requires-Dist: runtype (>=0.2.6,<0.3.0)
Requires-Dist: snowflake-connector-python (>=2.7.2,<3.0.0); extra == "snowflake"
Requires-Dist: textual (>=0.9.1,<0.10.0); extra == "tui"
Requires-Dist: textual-select; extra == "tui"
Requires-Dist: toml (>=0.10.2,<0.11.0)
Requires-Dist: trino (>=0.314.0,<0.315.0); extra == "trino"
Project-URL: Repository, https://github.com/datafold/sqeleton
Description-Content-Type: text/markdown

# Sqeleton

**Under construction!**

Sqeleton is a Python library for querying SQL databases.

It consists of -

- A fast and concise query builder, inspired by PyPika and SQLAlchemy

- A modular database interface, with drivers for a long list of SQL databases.

It is comparable to other libraries such as SQLAlchemy or PyPika, in terms of API and intended audience. However there are several notable ways in which it is different.

### Built for performance

- Multi-threaded by default -
    The same connection object can be used from multiple threads without any additional setup.

- No ORM
    ORMs are easy and familiar, but they encourage bad and slow code. Sqeleton is designed to push the compute to SQL.

- Fast query-builder
    Sqeleton's query-builder runs about 4 times faster than SQLAlchemy's.

### Type-aware

Sqeleton has a built-in feature to query the schemas of the databases it supports.

This feature can be also used to inform the query-builder, either as an alternative to defining the tables yourself, or to validate that your definitions match the actual schema.

The schema is used for validation when building expressions, making sure the names are correct, and that the data-types align.

### Multi-database access

Sqeleton is designed to work with several databases at the same time. Its API abstracts away as many implementation details as possible.

Databases we support:

- PostgreSQL >=10
- MySQL
- Snowflake
- BigQuery
- Redshift
- Oracle
- Presto
- Databricks
- Trino
- Clickhouse
- Vertica
- DuckDB >=0.6
- SQLite (coming soon)


### Documentation

[Read the docs!](https://sqeleton.readthedocs.io)

### Basic usage

```python
from sqeleton import connect, table, this

# Create a new database connection
ddb = connect("duckdb://:memory:")

# Define a table with one int column
tbl = table('my_list', schema={'item': int})

# Make a bunch of queries
queries = [
    # Create table 'my_list'
    tbl.create(),

    # Insert 100 numbers
    tbl.insert_rows([x] for x in range(100)),

    # Get the sum of the numbers
    tbl.select(this.item.sum())
]
# Query in order, and return the last result as an int
result = ddb.query(queries, int)    

# Prints: Total sum of 0..100 = 4950
print(f"Total sum of 0..100 = {result}")
```


# TODO

- Transactions

- Indexes

- Date/time expressions

- Window functions

## Possible plans for the future (not determined yet)

- Cache the compilation of repetitive queries for even faster query-building

- Compile control flow, functions

- Define tables using type-annotated classes (SQLModel style)

