Skip to main content

CodeQL Dependabot Updates test codecov Python Version from PEP 621 TOML

Sadel

Sadel is a helper class for upserting records with SQLModel.

Installation

pip install sadel

Example upsert

from sadel import Sadel
from sqlalchemy.ext.asyncio import create_async_engine
from sqlmodel import Field, create_engine, select, or_
from sqlmodel.ext.asyncio.session import AsyncSession

class Hero(Sadel, table=True):
    __tablename__ = "hero" 
    _upsert_index_elements = {"id"}

    id: int | None = Field(default=None, primary_key=True)
    name: str
    secret_name: str
    age: int | None = None

# Create
sqlite_url_async = "sqlite+aiosqlite:///database.db" 
async_engine = create_async_engine(sqlite_url_async, echo=True, future=True)


hero = Hero(name="Deadpond", secret_name="Dive Wilson")

async with AsyncSession(async_engine) as session:
    # Upsert the record
    await Hero.upsert(hero, session)
    
    # Fetch the upserted record
    result = (
        (await session.exec(select(Hero).where(Hero.name == "Deadpond")))
        .all()
    )

    print(result)

Output:

[Hero(id=1, name='Deadpond', secret_name='Dive Wilson', age=None, created_on=datetime.datetime(2024, 8, 1, 19, 39, 7), modified_on=None)]

Example batch upsert

hero_1 = Hero(name="Deadpond", secret_name="Dive Wilson")
hero_2 = Hero(name="Spider-Boy", secret_name="Pedro Parqueador")
hero_3 = Hero(name="Rusty-Man", secret_name="Tommy Sharp", age=48)

async with AsyncSession(async_engine) as session:
    await Hero.batch_upsert([hero_1, hero_2, hero_3], session)
    result = (
        (
            await session.exec(
               select(Hero).where(or_(Hero.name == "Deadpond",  Hero.name == "Spider-Boy", Hero.name == "Rusty-Man"))
            )
        )
        .all()
    )
    print(result)

Output:

[Hero(id=1, name='Deadpond', secret_name='Dive Wilson',age=None, created_on=datetime.datetime(2024, 8, 1, 19, 39, 7), modified_on=None), 
Hero(id=2, name='Spider-Boy", secret_name='Pedro Parqueador',age=None, created_on=datetime.datetime(2024, 8, 1, 19, 39, 7), modified_on=None),
Hero(id=3, name='Rusty-Man', secret_name='Tommy Sharp', age=48, created_on=datetime.datetime(2024, 8, 1, 19, 39, 7), modified_on=None)]

Example update record

async with AsyncSession(async_engine) as session:
    # Upsert the record
    hero = Hero(name="Deadpond", secret_name="Dive Wilson", age=25)
    await Hero.upsert(hero, session)

    # Update the record
    hero.age = 30
    # Upsert the updated record
    await Hero.upsert(hero, session)

    # Fetch the updated record
    result = (
        (await session.exec(select(Hero).where(Hero.name == "Deadpond")))
        .scalars()
        .all()
    )

    print(result)

Output:

[Hero(id=1, name='Deadpond', secret_name='Dive Wilson', age=30, created_on=datetime.datetime(2024, 8, 1, 19, 39, 7), modified_on=datetime.datetime(2024, 8, 1, 19, 39, 8))]

Features

  • Upsert and batch_upsert functions.
  • For auditing, automatically adds and manages created_on and modified_on columns to your table (timezones are supported).
  • Validates your data before upserting using Pydantic validate_model method (not supported in SQLModel)
  • Asyncio
  • Compatible with Alembic
  • Specify the (PK) columns to use for upserting using _upsert_index_elements attribute
  • Ignore specific columns from updating using _upsert_exclude_fields attribute

Contributing

  • Fork the repository
  • Create a new branch
  • Make your changes
  • Raise a PR

License

This project is licensed under the terms of the MIT License

Metadata

Release files for sadel 0.1.1

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

Source distribution (sdist)

Source distribution for sadel 0.1.1
File Size Uploaded
sadel-0.1.1.tar.gz 5.1 kB Details

Built distribution (wheel)

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

Total release size: 9.9 kB

Release files / sadel-0.1.1.tar.gz

Download URL sadel-0.1.1.tar.gz
Size 5.1 kB
Tags Source
SHA-256 checksum
How to use checksums
299c0a9746d91ce10e519213c4e672be8104ce736bed0739212dfbbaead77834
BLAKE2b-256 checksum
How to use checksums
c739836811146b6f39150588af783a5a57d7aa9d05eed283b7fc7bffc0c77d77
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 11, 2025.

Transparency log

Release files / sadel-0.1.1-py3-none-any.whl

Download URL sadel-0.1.1-py3-none-any.whl
Size 4.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
b0b10cc3c1e1c6a56a2e438a76c371a5a0dbe08d97e585faf3424c4799f657a8
BLAKE2b-256 checksum
How to use checksums
205a0ab31ff12fccec7bd601e3005233e2f679a1330f2b54ca4ef0377d0ad89a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 11, 2025.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 release files

0.1.0

2 release files

0.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