Skip to main content

Sustained.py

A Python query builder and lightweight ORM inspired by Objection.js.

Sustained builds parameterized SQL for the default (ANSI), Postgres, MSSQL, Presto, and DuckDB dialects. It executes queries against any DB-API 2.0 connection or connection pool with transactions, hydrates rows into model instances or DataFrames, writes data with insert(), update(), delete(), upserts, and INSERT ... SELECT, and eager loads relations. Filters compose as typed predicates: User.query().where((User.c.age > 21) & User.c.name.like('A%')). Models can declare typed columns and generate their DDL, an explicit migration runner manages schema changes, and async services run the same queries through driver adapters with await query.arun().

Installation

python3 -m pip install sustained

Local Installation from Source

To install sustained from source for local development:

  1. Clone the repository:

    git clone https://github.com/wetherc/sustained.git
    cd sustained
    
  2. Install in editable mode:

    python3 -m pip install -e .
    

Usage

from sustained import Model, RelationType, create_model

class Person(Model):
    database = 'my_db'
    tableSchema = 'public'
    tableName = 'persons'

class Animal(Model):
    tableName = 'animals'

    relationMappings = {
        'owner': {
            'relation': RelationType.BelongsToOneRelation,
            'modelClass': Person,
            'join': {
                'from': 'animals.ownerId',
                'to': 'persons.id'
            }
        }
    }

# Build a query
query = Animal.query().select('animals.name', 'persons.name').leftOuterJoinRelated('owner')

print(query)
# SELECT animals.name, persons.name
# FROM animals
# LEFT OUTER JOIN persons
#   ON animals.ownerId = persons.id


# Build a more complex query with a CTE and a raw join
active_owners = Person.query().select('id').where('status', '=', 'active')

query = (
    Animal.query()
    .with_('active_owners', active_owners)
    .join('active_owners', 'animals.ownerId', '=', 'active_owners.id')
    .select('animals.name')
)

print(query)
# WITH active_owners AS (
#   SELECT id
#   FROM persons
#   WHERE status = 'active'
# )
# SELECT animals.name
# FROM animals
# JOIN active_owners
#   ON animals.ownerId = active_owners.id


# Execute against any DB-API 2.0 connection
import sqlite3

conn = sqlite3.connect('app.db')
Animal.bind(conn)

# Parameterized execution with model hydration
animals = Animal.query().where('species', '=', 'dog').orderBy('name').run()

# Or take the SQL and parameters and execute them yourself
sql, params = Animal.query().where('species', '=', 'dog').to_sql()
# sql:    "SELECT * FROM animals WHERE species = ?"
# params: ('dog',)

See the documentation for models, filtering, grouping, relations, and execution guides.

Development

This project uses pre-commit to enforce code quality and run tests before committing code.

Pre-commit Hooks Setup

  1. Install pre-commit:

    pip install pre-commit
    
  2. Install the Git hooks: From the root of the project directory, run:

    pre-commit install
    

Release files for sustained 2.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 sustained 2.2.0
File Size Uploaded
sustained-2.2.0.tar.gz 101.2 kB Details

Built distribution (wheel)

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

Total release size: 166.5 kB

Release files / sustained-2.2.0.tar.gz

Download URL sustained-2.2.0.tar.gz
Size 101.2 kB
Tags Source
SHA-256 checksum
How to use checksums
fccc76f3020f4ead7c003baebf59e0a58ef537f98f78ee274709f46fa8394e58
BLAKE2b-256 checksum
How to use checksums
9f8f9253c5e72c178b88da52eb984dd0d28e61057de18a85391d78a5a7d84eef
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.6

Release files / sustained-2.2.0-py3-none-any.whl

Download URL sustained-2.2.0-py3-none-any.whl
Size 65.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
9d34c545327e13ac380271e291a98a9c309098165fdd183d927363c351c6bb23
BLAKE2b-256 checksum
How to use checksums
6411617a8c4deac72cdbc3cc826536c5697e2148e4f504bf3f155c1f1ba17b4b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.6

Release history Release notifications | RSS feed

2.25.0

2 release files

2.24.2

2 release files

2.23.1

2 release files

2.23.0

2 release files

2.22.0

2 release files

2.21.0

2 release files

2.20.0

2 release files

2.19.0

2 release files

2.18.0

2 release files

2.17.0

2 release files

2.16.1

2 release files

2.16.0

2 release files

2.15.0

2 release files

2.14.0

2 release files

2.13.0

2 release files

2.12.0

2 release files

2.11.0

2 release files

2.10.0

2 release files

2.9.0

2 release files

2.8.0

2 release files

2.7.0

2 release files

2.6.0

2 release files

2.5.0

2 release files

2.4.0

2 release files

2.3.0

2 release files

This release

2.2.0 This release

2 release files

2.1.0

2 release files

2.0.0

2 release files

1.1.0

2 release files

1.0.2

2 release files

1.0.1

2 release files

1.0.0

2 release files

0.0.7

2 release files

0.0.6

2 release files

0.0.5

2 release files

0.0.4

2 release files

0.0.3

2 release files

0.0.2

2 release files

0.0.1

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