SQLAlchemy with Active Record - a fluent query builder and ActiveRecord implementation for SQLAlchemy
Project description
Flex Alchemy
Use SQLAlchemy with Active Record pattern.
Installation
pip install flex-alchemy
Quick Start
-
Declare Models and inherit ActiveRecord
# models.py from sqlalchemy.orm import DeclarativeBase from sqlalchemy import String, BigInteger, Boolean from sqlalchemy.orm import Mapped, mapped_column from flex_alchemy import ActiveRecord class Base(DeclarativeBase, ActiveRecord): pass class User(Base): __tablename__ = "users" id: Mapped[int] = mapped_column(BigInteger(), primary_key=True) email: Mapped[str] = mapped_column(String(), unique=True) password: Mapped[str] = mapped_column(String()) name: Mapped[str] = mapped_column(String(50)) enable: Mapped[bool] = mapped_column(Boolean(), default=True)
-
Create SQLAlchemy Engine, and assign to session handler in
ActiveRecord# database.py from sqlalchemy import create_engine from models import Base engine = create_engine("sqlite:///:memory:") Base.make_session(engine)
-
Start using model to operate database!
from models import User users = User.all() # [User(id=1), User(id=2), ...]
-
Release session resource after use
from models import Base Base.teardown_session()
Usage
Create Records
# Option #1: Use class method `create`
user = User.create(
name="John Doe",
email="john.doe@example.com",
password="secure_password"
)
# Option #2: Create model instance and call `save` method
user = User(
name="Jane Doe",
email="jane.doe@example.com",
password="another_password"
)
user.save()
Query Records
# find a record by primary key
user = User.find(1)
# find all records
all_users = User.all()
# find a record with specific columns
row = User.select(User.id, User.name, User.email).execute().first()
# find records with conditions
active_users = User.where(User.enable.is_(True)).execute().scalars().all()
Update Records
# find a record and update it by calling `save` method
user = User.find(1)
user.name = "New Name"
user.save()
# Update multiple records with conditions
User.update(updated_at=datetime.now()).where(User.enalbe.is_(True)).execute()
Delete Records
# delete a record by calling `delete` method
user = User.find(1)
user.delete()
# delete multiple records
User.destroy().where(User.enable.is_(False)).execute()
Examples
Use in FastAPI
from contextlib import asynccontextmanager
from fastapi import FastAPI, Depends
from sqlalchemy import create_engine
from app.models import Base, User
engine = create_engine("postgresql://user:password@localhost/dbname")
@asynccontextmanager
async def lifespan(app: FastAPI):
"""
Make scoped session with engine when FastAPI start
"""
Base.make_session(engine)
yield
def close_session():
"""
cleanup scoped session after each request
"""
yield
Base.teardown_session()
app = FastAPI(
title="MyApp",
lifespan=lifespan,
dependencies=[Depends(close_session)],
)
@app.get("/users")
def index():
"""get all users"""
return User.all()
@app.get("/users/{id_}")
def show(id_: int):
"""get user by id"""
return User.find(id_)
@app.post("/users")
def create(user_data: dict):
"""create a new user"""
return User.create(user_data)
Others
Use Session instead of Scoped Session
flex-alchemy provides a way to use Session instead of ScopedSession by pass a Session instance to execute method.
from sqlalchemy import create_engine
from sqlalchemy.orm import Session
engine = create_engine("sqlite:///:memory:")
with Session(engine) as session:
# find all users
User.all(session=session)
# find a user by primary key
User.find(1, session=session)
# create a new user
User.create({
"name": "New User",
"email": "example@mail.com"
"password": "password"
}, session=session)
user = User(
name="New User",
email="example@mail.com",
password="password"
)
user.save(session=session)
User.where(User.enable.is_(True)).execute(session=session).scalars().all()
... etc
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file flex_alchemy-0.1.0.tar.gz.
File metadata
- Download URL: flex_alchemy-0.1.0.tar.gz
- Upload date:
- Size: 5.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/2.1.1 CPython/3.10.11 Darwin/24.1.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
dc7d01ab5d148f94e17b5dae81ecd5f55b16c7c40bb1bf0af91195d994f2414b
|
|
| MD5 |
f12bac55c095b6b1f7e8fe7f92fc038e
|
|
| BLAKE2b-256 |
c825e8fbcb5132a7faed23a682a0d2a5d1dca51afc32bfae86ee29bcb6604348
|
File details
Details for the file flex_alchemy-0.1.0-py3-none-any.whl.
File metadata
- Download URL: flex_alchemy-0.1.0-py3-none-any.whl
- Upload date:
- Size: 10.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/2.1.1 CPython/3.10.11 Darwin/24.1.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
179a7bb3022cf43f5ac3f7935e6178198fa965826b5169a37f134391eaafb94a
|
|
| MD5 |
1ef3940a140679bcb994f974aa09aecf
|
|
| BLAKE2b-256 |
ca013ca94cb91fc7ce3433c4727981177420cab1c9216ede937dce1578e695d5
|