Uma biblioteca robusta de repositórios genéricos combinando SQLAlchemy e Pydantic.
Project description
lansuSql
A robust, fully-typed Generic Repository library for Python, bridging the gap between SQLAlchemy and Pydantic.
Say goodbye to repetitive database queries. lansuSql provides an elegant, Django-style ORM experience for your FastAPI/SQLAlchemy projects, complete with dynamic filtering and native DTO support.
pip install lansuSql
Features
- CRUD Out-of-the-Box: Standard methods for creating, reading, updating, and deleting records without writing repetitive SQLAlchemy statements.
- Django-style Dynamic Filters: Query your database intuitively using operators like
__gt,__lt,__gte,__in,__nin,__like, and more (e.g.,repo.find_by(age__gt=18)). - Native Pydantic Support: Pass Pydantic DTOs directly to
createandupdatemethods. The repository handles the conversion and data extraction automatically. - Fully Typed: Built with Python
typingandGenerictypes. Enjoy perfect IDE autocompletion and static type checking. - Zero Coupling: Keeps your business logic (Services/Controllers) completely independent from SQLAlchemy's
Sessionmechanics. - Safer Defaults: Invalid filters and update fields raise clear errors by default, preventing accidental broad queries.
📦 Installation
pip install lansuSql
Quick Start
1. Define your SQLAlchemy Model
from sqlalchemy import Column, Integer, String, Boolean
from sqlalchemy.orm import declarative_base
Base = declarative_base()
class User(Base):
__tablename__ = "users"
id = Column(Integer, primary_key=True, autoincrement=True)
name = Column(String)
age = Column(Integer)
is_active = Column(Boolean, default=True)
2. Create a Repository for your Model
from lansuSql import BaseRepository
class UserRepository(BaseRepository[User]):
# You can add custom methods here if needed,
# but all standard CRUD operations are inherited automatically!
pass
3. Use it in your Application (e.g., FastAPI)
from fastapi import Depends
from sqlalchemy.orm import Session
from .database import get_db
# Example Pydantic DTO
from pydantic import BaseModel
class UserCreateDTO(BaseModel):
name: str
age: int
def create_user(dto: UserCreateDTO, db: Session = Depends(get_db)):
repo = UserRepository(model=User, session=db)
# Pass the DTO directly!
# Auto-commit=True saves it to the database immediately.
new_user = repo.create(dto, auto_commit=True)
return new_user
Dynamic Filtering (find_by) The crown jewel of lansuSql is its dynamic filtering capability. You can use magic operators to build complex queries effortlessly:
repo = UserRepository(User, db)
# Find exact matches
admins = repo.find_by(is_active=True, role="ADMIN")
# Find with operators (Greater than)
adults = repo.find_by(age__gt=18)
# Find with multiple conditions (Less than or equal + Exact match)
young_actives = repo.find_by(age__lte=25, is_active=True)
# Find in a list of values
selected_users = repo.find_by(id__in=[1, 5, 10])
# Exclude values
non_admins = repo.find_by(role__nin=["ADMIN", "OWNER"])
# Search text
matching_users = repo.find_by(name__ilike="tiago")
Pagination and Ordering
# Order ascending by age
users = repo.list_all(order_by="age")
# Order descending by created_at
recent_users = repo.find_by(is_active=True, order_by="-created_at")
# Limit and offset
page = repo.find_by(is_active=True, order_by="-created_at", limit=20, offset=40)
By default, invalid fields and operators raise ValueError. If you need the old permissive behavior, pass strict=False to find_by, first_by, count, or exists.
🔍 Supported Operators:
__eq: Equal (Default if no operator is passed)__neq: Not equal__gt: Greater than__gte: Greater than or equal to__lt: Less than__lte: Less than or equal to__in: In a given list__nin: Not in a given list__like: SQLLIKEwith%value%__ilike: Case-insensitive SQLLIKEwith%value%
🛠️ API Reference:
- get_by_id(id): Retrieves a single record by its primary key.
- list_all(limit=None, offset=None, order_by=None): Retrieves records in the table, optionally ordered and paginated.
- find_by(**kwargs): Returns records matching dynamic filters. Supports
limit,offset,order_by, andstrict. - first_by(**kwargs): Returns the first record matching dynamic filters.
- count(**kwargs): Counts records matching dynamic filters.
- exists(**kwargs): Returns
Truewhen at least one record matches dynamic filters. - create(obj_in, auto_commit=False): Creates a new record from a dict or Pydantic DTO.
- update(instance, obj_in, auto_commit=False, strict=True): Updates an existing record using a dict or Pydantic DTO. Ignores unset Pydantic fields automatically.
- delete(instance, auto_commit=False): Deletes the record from the database.
- save(instance, auto_commit=False): Manually adds and commits an SQLAlchemy instance to the session.
🧪 Running Tests
The library is fully tested using pytest and an in-memory SQLite database to ensure reliability.
pip install -e ".[dev]"
pytest -v
📄 License
This project is licensed under 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
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 lansusql-0.2.0.tar.gz.
File metadata
- Download URL: lansusql-0.2.0.tar.gz
- Upload date:
- Size: 11.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1eb0d530717e983e292e060b657306f118c6de305257ddbbf9dc5700f20265c3
|
|
| MD5 |
536a303ade9c7d2a437d65285a432d34
|
|
| BLAKE2b-256 |
4c1b574e1d7e43a1c702878fab20bdf72a5f48d8781dff3d7976fe1e39dd5a2d
|
File details
Details for the file lansusql-0.2.0-py3-none-any.whl.
File metadata
- Download URL: lansusql-0.2.0-py3-none-any.whl
- Upload date:
- Size: 9.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
28cab76db9704ca3e944f4994ed23476037bc40f946df010a056b9d75f458894
|
|
| MD5 |
7cf582a9374df4590a52113e74dc5f6a
|
|
| BLAKE2b-256 |
67df878e908cd3fff823062f3e091e4f03ccbd38d4da2172569510e0569937e4
|