Skip to main content

A low-level SQL library that builds parameterized SQL queries through Python operator overloading

Project description

SQLPiston

test lint coverage pypi python license

Write once, query everywhere — build SQL with Python operators.

中文版

SQLPiston is a low-level SQL library that builds parameterized SQL queries through Python operator overloading. AST nodes carry zero SQL knowledge; dialect-specific compilers translate the same AST into the right SQL for each database.

Install

git clone https://github.com/MuliMuri/sqlpiston.git
cd sqlpiston
pip install -e .

Python 3.9+ on Linux / macOS / Windows.

Basic Usage

from sqlpiston import Select, Field, Insert
from sqlpiston import DBEngine, DBType, Session
from dataclasses import dataclass

eng = DBEngine(DBType.SQLite)
eng.init_engine(":memory:")
session = Session(eng)

stmt = (
    Select()
    .select("id", "name", "age")
    .from_table("users")
    .where((Field("age") >= 18) & (Field("status") == "active"))
    .order_by("id", "ASC")
    .limit(10)
)
result = session.execute(stmt)

@dataclass
class User:
    id: int
    name: str
    age: int

users = result.map(User)

session.execute(
    Insert().into("users").values({"name": "Alice", "age": 25})
)

session.commit()
session.close()
More examples: JOIN, subquery, CTE, UPSERT, DDL

JOIN

Select() \
    .select("users.name", "orders.total") \
    .from_table("users") \
    .join("orders",
          Field("user_id", "orders") == Field("id", "users")) \
    .where(Field("total", "orders") > 100)

Subquery (IN / EXISTS / Scalar)

# IN subquery
admin_ids = Select().select("id").from_table("admins")
stmt = Select().select("name").from_table("users") \
    .where(Field("id").is_in(admin_ids))

# EXISTS
sub = Select().select("1").from_table("orders") \
    .where(Field("user_id", "orders") == Field("id", "users"))
stmt = Select().select("name").from_table("users").where(sub.exists())

# Scalar
avg = Select().select(SQLFunction("avg", "salary")).from_table("employees")
stmt = Select().select("name").from_table("staff").where(Field("salary") > avg)

CTE

cte = Select().select("*").from_table("sales") \
    .where(Field("amount") > 100).cte("big_sales")
stmt = Select().with_(cte).select("*").from_table("big_sales")

UPSERT — same AST, different SQL per dialect

Upsert() \
    .into("users") \
    .values({"id": 1, "name": "X"}) \
    .on_conflict("id") \
    .do_update({"name": "X"})
Dialect Generated SQL
MySQL INSERT INTO ... ON DUPLICATE KEY UPDATE
SQLite INSERT INTO ... ON CONFLICT DO UPDATE

DDL

CreateTable().table("users").if_not_exists() \
    .column("id", "INTEGER", primary_key=True, nullable=False) \
    .column("name", "VARCHAR(255)")

AlterTable().table("users").add_column("age", "INTEGER", default=0)

DropTable().table("users").if_exists()

Highlights

  • Operator overloadingField("age") >= 18 builds AST, not a boolean
  • Dialect-aware — same AST compiles to MySQL (%s, backticks) or SQLite (?, double-quotes)
  • Full standard SQL — SELECT, INSERT, UPDATE, DELETE, UPSERT, CTE, UNION, subqueries, DDL
  • Parameterized by design — values never interpolated into SQL strings
  • Weak ORM — result-to-dataclass mapping, no identity map or change tracking

Documentation

cd docs
pip install -r requirements.txt
sphinx-build -b html source build/html

License

MIT

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

sqlpiston-0.1.0.tar.gz (31.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

sqlpiston-0.1.0-py3-none-any.whl (23.1 kB view details)

Uploaded Python 3

File details

Details for the file sqlpiston-0.1.0.tar.gz.

File metadata

  • Download URL: sqlpiston-0.1.0.tar.gz
  • Upload date:
  • Size: 31.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for sqlpiston-0.1.0.tar.gz
Algorithm Hash digest
SHA256 3479e70e1f8d104da693b2290d7af7e0f5c4f22a40760fe9c1926e9ded16cbfd
MD5 53d2411a694242a4a7cd87560ae1e12f
BLAKE2b-256 60ce2c122f924bc3570805f7c3edf44c80c1aeedc61d566affc9adf1a4385db4

See more details on using hashes here.

Provenance

The following attestation bundles were made for sqlpiston-0.1.0.tar.gz:

Publisher: publish.yml on MuliMuri/sqlpiston

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file sqlpiston-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: sqlpiston-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 23.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for sqlpiston-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 1d7edbc56233fe17398c02957416c1883d2980d45eb5fb071e7d82da36dcd9ef
MD5 d6409bed09ba218b59dced156669bafe
BLAKE2b-256 074e3da766cf9ea271b8d6be67471f271b10925178b4dcd2fba4e161059a73aa

See more details on using hashes here.

Provenance

The following attestation bundles were made for sqlpiston-0.1.0-py3-none-any.whl:

Publisher: publish.yml on MuliMuri/sqlpiston

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

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