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.1.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.1-py3-none-any.whl (23.1 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: sqlpiston-0.1.1.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.1.tar.gz
Algorithm Hash digest
SHA256 e78faad64010f83d8cb07ff79485cb5e83057ec5d1713eef15cb3dadc647002f
MD5 2bcc9fc95bf57bb19eb5ae49acbefa8b
BLAKE2b-256 0c9914d11c0472454431059bcb0834134f28dca34a97a4be7ebe11f01047a7aa

See more details on using hashes here.

Provenance

The following attestation bundles were made for sqlpiston-0.1.1.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.1-py3-none-any.whl.

File metadata

  • Download URL: sqlpiston-0.1.1-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.1-py3-none-any.whl
Algorithm Hash digest
SHA256 5c74dcef1bbda043469105c101d6328bfa31ef3a3c5a60136b96744975a0e9b8
MD5 c446b343229c2bf72181f7a8bb940f3c
BLAKE2b-256 471baa38b3fe75d03d2cc14cf701cda7a64f4946c486d3e5b102dbf1126c4392

See more details on using hashes here.

Provenance

The following attestation bundles were made for sqlpiston-0.1.1-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