Skip to main content

Simplifies upserting records to database

Project description

Sadel

Sadel simplifies upserting records to your database by extending SQLModel. It adds a single line of code to upsert records to your database. It also supports batch upserting records. In addition, it automatically adds and manages created_on and modified_on columns to your table for auditing purposes and validates the record before upserting.

Features

  • (Batch) upsert records with a single line of code.
  • Asyncio support
  • For auditing, automatically adds and manages created_on and modified_on columns to your table
  • Validates your data before upserting using Pydantic validate_model method (not supported in SQLModel)

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"  # type: ignore
    _upsert_index_elements = {"id"}

    id: int | None = Field(default=None, primary_key=True)
    name: str
    secret_name: str
    age: int | None = None
    
sqlite_url = f"sqlite+aiosqlite::///database.db" 
engine = create_engine(sqlite_url, echo=True, future=True)

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', 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', created_on=datetime.datetime(2024, 8, 1, 19, 39, 7), modified_on=None), 
Hero(id=2, name='Spider-Boy", secret_name='Pedro Parqueador', created_on=datetime.datetime(2024, 8, 1, 19, 39, 7), modified_on=None),
Hero(id=3, name='Rusty-Man', secret_name='Tommy Sharp', created_on=datetime.datetime(2024, 8, 1, 19, 39, 7), modified_on=None)]

Installation

pip install sadel

Contributing

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

Development

# install dependencies
rye sync 
# run tests, linting, formatting, and type checking, 
rye run all

License

This project is licensed under the terms of the MIT License

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

sadel-0.0.0.tar.gz (4.6 kB view details)

Uploaded Source

Built Distribution

sadel-0.0.0-py3-none-any.whl (4.5 kB view details)

Uploaded Python 3

File details

Details for the file sadel-0.0.0.tar.gz.

File metadata

  • Download URL: sadel-0.0.0.tar.gz
  • Upload date:
  • Size: 4.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/5.1.0 CPython/3.12.4

File hashes

Hashes for sadel-0.0.0.tar.gz
Algorithm Hash digest
SHA256 1c06d3629642cf35af2710fbd337ec42fd120cf54a54498ac5d37575d92c9598
MD5 ff9c3b4c7d638f1cf73bab0244cedb4d
BLAKE2b-256 0f2e19bd7cfbca9a0559bf16e40e67a960465e7c3c15f186ca2fee5538c1c53a

See more details on using hashes here.

File details

Details for the file sadel-0.0.0-py3-none-any.whl.

File metadata

  • Download URL: sadel-0.0.0-py3-none-any.whl
  • Upload date:
  • Size: 4.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/5.1.0 CPython/3.12.4

File hashes

Hashes for sadel-0.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 921b6e49229d0d7d0c16e750964f517810d8837d6cf385bb52f68faab022c02b
MD5 d0d83d61dfedab106fb52fd16c4d49ac
BLAKE2b-256 88cf863c09259019c58cda8a33f6fe81630a178e9fcc3ff2a54e99a1af1573a9

See more details on using hashes here.

Supported by

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