Skip to content

Commit 2e84ce2

Browse files
committed
updated README.md; patching release.yml
1 parent 42ba061 commit 2e84ce2

2 files changed

Lines changed: 307 additions & 33 deletions

File tree

.github/workflows/release.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,9 @@ jobs:
5050
- name: Install dependencies with uv
5151
run: |
5252
# Install packages from requirements.txt and additional tools
53-
uv pip install -r requirements.txt pytest pytest-cov pre-commit build twine
53+
uv pip install -r core_requirements.txt
54+
uv pip install -r dev_requirements.txt
55+
build twine
5456
5557
- name: Run pre-commit hooks
5658
uses: pre-commit/action@v3.0.1

README.md

Lines changed: 304 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,304 @@
1-
# SQLModel-CRUD-Utilities
2-
A set of CRUD utilities to expedite operations with SQLModel.
3-
4-
## Instructions
5-
6-
- Run `pip install sqlmodel_crud_utils` or add `sqlmodel_crud_utils` to your
7-
requirements files
8-
- Declare the value for the `SQL_DIALECT` environmental variable. It can either
9-
be actively loaded within the environment or added to a `.env` file, courtesy
10-
of `dotenv`.
11-
- For a list of available native and 3rd party dialects, please see here: https://docs.sqlalchemy.org/en/20/dialects/#included-dialects
12-
13-
## Inspiration
14-
The reason behind creating this package was to streamline the CRUD operations
15-
across multiple personal and team-based projects that rely on SQLModel for its
16-
ORM operations.
17-
18-
Because of existing commitments to SQLModel within the tech stack of multiple
19-
projects, this package will be continuously supported and developed. A close eye
20-
will be kept on the SQLModel's ongoing roadmap and eventual uplift to SQLAlchemy
21-
2.0 and Pydantic 2.0.
22-
## Development Roadmap
23-
- [x] Release working Alpha version
24-
- [x] Test across existing projects to ensure complete coverage
25-
- [ ] 100% test coverage
26-
- [ ] Complete autonomous CICD for on-demand testing and building
27-
28-
## Roadmap
29-
- [ ] Alpha release
30-
- [ ] Beta release
31-
- [ ] Solicit community feedback
32-
- [ ] 360 Development Review
1+
<div align="left" style="position: relative;">
2+
<img src="https://raw.githubusercontent.com/PKief/vscode-material-icon-theme/ec559a9f6bfd399b82bb44393651661b08aaf7ba/icons/folder-markdown-open.svg" align="right" width="30%" style="margin: -20px 0 0 20px;">
3+
<h1>SQLMODEL_CRUD_UTILS</h1>
4+
<p align="left">
5+
<em>A set of CRUD (Create, Read, Update, Delete) utilities designed to
6+
streamline and expedite common database operations when using SQLModel, offering both synchronous and asynchronous support.</em>
7+
</p>
8+
<p align="left">
9+
<!-- Add relevant badges here if/when hosted publicly, e.g., PyPI version, build status, coverage -->
10+
<!-- Example:
11+
<a href="https://pypi.org/project/sqlmodel-crud-utils/"><img alt="PyPI - Version" src="https://img.shields.io/pypi/v/sqlmodel-crud-utils"></a>
12+
<a href="https://github.com/YOUR_USERNAME/sqlmodel-crud-utils/actions/workflows/release.yml"><img alt="CI Status" src="https://github.com/YOUR_USERNAME/sqlmodel-crud-utils/actions/workflows/release.yml/badge.svg"></a>
13+
<a href="https://codecov.io/gh/YOUR_USERNAME/sqlmodel-crud-utils"><img src="https://codecov.io/gh/YOUR_USERNAME/sqlmodel-crud-utils/branch/main/graph/badge.svg"/></a>
14+
-->
15+
</p>
16+
<p align="left">Built with the tools and technologies:</p>
17+
<p align="left">
18+
<img src="https://img.shields.io/badge/Python-3776AB.svg?style=default&logo=Python&logoColor=white" alt="Python">
19+
<img src="https://img.shields.io/badge/SQLModel-488efc.svg?style=default&logo=Python&logoColor=white" alt="SQLModel">
20+
<img src="https://img.shields.io/badge/SQLAlchemy-D71F00.svg?style=default&logo=Python&logoColor=white" alt="SQLAlchemy">
21+
<img src="https://img.shields.io/badge/pytest-0A9EDC.svg?style=default&logo=pytest&logoColor=white" alt="pytest">
22+
<img src="https://img.shields.io/badge/uv-43ccAC.svg?style=default&logo=Python&logoColor=white" alt="uv">
23+
</p>
24+
</div>
25+
<br clear="right">
26+
27+
## Table of Contents
28+
29+
- [ Overview](#-overview)
30+
- [Features](#-features)
31+
- [ Project Structure](#-project-structure)
32+
- [ Project Index](#-project-index)
33+
- [ Getting Started](#-getting-started)
34+
- [ Prerequisites](#-prerequisites)
35+
- [ Configuration](#-configuration)
36+
- [ Installation](#-installation)
37+
- [ Usage](#-usage)
38+
- [ Testing](#-testing)
39+
- [ Project Roadmap](#-project-roadmap)
40+
- [ Contributing](#-contributing)
41+
- [ License](#-license)
42+
- [ Acknowledgments](#-acknowledgments)
43+
44+
---
45+
46+
## Overview
47+
`sqlmodel-crud-utils` provides a convenient layer on top of SQLModel and SQLAlchemy to simplify common database interactions. It offers both synchronous and asynchronous functions for creating, reading, updating, and deleting data, along with helpers for bulk operations, filtering, pagination, and relationship loading. The goal is to reduce boilerplate code in
48+
projects using SQLModel.
49+
50+
---
51+
52+
## Features
53+
54+
- **Sync & Async Support:** Provides parallel functions in `sqlmodel_crud_utils.sync` and `sqlmodel_crud_utils.a_sync`.
55+
- **Simplified CRUD:** Offers high-level functions:
56+
- `get_one_or_create`:
57+
Retrieves an existing record or creates a new one.
58+
- `get_row`: Fetches a single row by primary key.
59+
- `get_rows`: Fetches multiple rows with flexible filtering, sorting, and pagination.
60+
- `get_rows_within_id_list`: Fetches rows matching a list of primary keys.
61+
- `update_row`: Updates fields of an existing row.
62+
- `delete_row`: Deletes a row by primary key.
63+
- `write_row`: Inserts a single new row.
64+
- `insert_data_rows`: Inserts multiple new rows with fallback for individual insertion on bulk failure.
65+
- `bulk_upsert_mappings`: Performs bulk insert-or-update operations (dialect-aware).
66+
- **Relationship Loading:** Supports eager loading (`selectinload`) and lazy loading (`lazyload`) via parameters in `get_row` and `get_rows`.
67+
- **Flexible Filtering:** `get_rows` supports filtering by exact matches (`filter_by`) and common comparisons (`__like`, `__gte`, `__lte`, `__gt`, `__lt`, `__in`) using keyword arguments.
68+
- **Pagination:** Built-in pagination for `get_rows`.
69+
- **Dialect-Specific Upsert:** Automatically uses the correct `upsert` syntax (e.g., `ON CONFLICT DO UPDATE` for PostgreSQL/SQLite) based on the `SQL_DIALECT` environment variable.
70+
- **Error Handling:** Includes basic error logging via `loguru` and session rollback on exceptions.
71+
72+
---
73+
74+
## Project Structure
75+
76+
77+
```sh
78+
└── sqlmodel_crud_utils/
79+
├── __init__.py
80+
├── __pycache__
81+
│ ├── __init__.cpython-313.pyc
82+
│ ├── a_sync.cpython-313.pyc
83+
│ ├── sync.cpython-313.pyc
84+
│ └── utils.cpython-313.pyc
85+
├── a_sync.py
86+
├── sync.py
87+
└── utils.py
88+
```
89+
90+
91+
### Project Index
92+
<details open>
93+
<summary><b><code>sqlmodel_crud_utils/</code></b></summary>
94+
<details> <!-- __root__ Submodule -->
95+
<summary><b>__root__</b></summary>
96+
<blockquote>
97+
<table>
98+
<tr>
99+
<td><b><a href='sqlmodel_crud_utils/blob/master/a_sync.py'>a_sync.py</a></b></td>
100+
<td>Contains asynchronous versions of the CRUD utility functions, designed for use with `asyncio` and async database drivers (e.g., `aiosqlite`, `asyncpg`).</td>
101+
</tr>
102+
<tr>
103+
<td><b><a href='sqlmodel_crud_utils/blob/master/sync.py'>sync.py</a></b></td>
104+
<td>Contains synchronous versions of the CRUD utility functions for standard execution environments.</td>
105+
</tr>
106+
<tr>
107+
<td><b><a href='sqlmodel_crud_utils/blob/master/utils.py'>utils.py</a></b></td>
108+
<td>Provides shared helper functions used by both `sync.py` and `a_sync.py`, such as environment variable retrieval and dynamic dialect-specific import logic for upsert statements.</td>
109+
</tr>
110+
</table>
111+
</blockquote>
112+
</details>
113+
</details>
114+
115+
---
116+
117+
118+
---
119+
## Getting Started
120+
121+
### Prerequisites
122+
123+
- **Python:** Version 3.8+ recommended.
124+
- **Database:** A SQLAlchemy-compatible database (e.g., PostgreSQL, SQLite, MySQL).
125+
- **SQLModel:** Your project should be using SQLModel for ORM definitions.
126+
127+
### Configuration
128+
129+
This package requires the `SQL_DIALECT` environment variable to be set for the `upsert` functionality to work correctly across different database backends.
130+
131+
Set it in your environment:
132+
```bash
133+
export SQL_DIALECT=postgresql # or sqlite, mysql, etc
134+
```
135+
136+
Or add it to a `.env` file in your project root (will be loaded automatically via `python-dotenv`):
137+
138+
```.env
139+
SQL_DIALECT=postgresql
140+
```
141+
142+
Refer to SQLAlchemy Dialects for a list of supported dialect names.
143+
144+
### Installation
145+
146+
**Install from PyPI (Recommended):**
147+
```bash
148+
pip install sqlmodel-crud-utils
149+
# Or using uv:
150+
uv pip install sqlmodel-crud-utils
151+
```
152+
**Build from source:**
153+
154+
1. Clone the sqlmodel_crud_utils repository:
155+
```sh
156+
git clone https://github.com/fsecada01/SQLModel-CRUD-Utilities.git
157+
```
158+
159+
2. Navigate to the project directory:
160+
```sh
161+
cd sqlmodel_crud_utils
162+
```
163+
164+
3. Install the project dependencies:
165+
166+
```bash
167+
uv pip install -r core_requirements.txt
168+
# For testing/development
169+
uv pip install -r dev_requirements.txt
170+
```
171+
*(Alternatively, use `pip install -r requirements.txt && pip install .`)*
172+
173+
174+
### Usage
175+
176+
Import the desired functions from either the `sync` or `a_sync` module and use them with your SQLModel session and models.
177+
178+
**Example (Synchronous):**
179+
180+
```python
181+
182+
from sqlmodel import Session, SQLModel, create_engine, Field
183+
from sqlmodel_crud_utils.sync import get_one_or_create, get_rows
184+
185+
# Assume MyModel is defined and engine is created
186+
187+
class MyModel(SQLModel, table=True):
188+
id: int | None = Field(default=None, primary_key=True)
189+
name: str = Field(index=True)
190+
value: int | None = None
191+
192+
DATABASE_URL = "sqlite:///./mydatabase.db"
193+
engine = create_engine(DATABASE_URL)
194+
195+
SQLModel.metadata.create_all(engine)
196+
197+
with Session(engine) as session:
198+
# Get or create an instance
199+
instance, created = get_one_or_create(
200+
session_inst=session, model=MyModel,
201+
name="Test Item", create_method_kwargs={"value": 123}
202+
)
203+
print(f"Instance ID: {instance.id}, Was created: {not created}")
204+
205+
# Get rows matching criteria
206+
success, rows = get_rows(
207+
session_inst=session,
208+
model=MyModel,
209+
value__gte=100,
210+
sort_field="name"
211+
)
212+
if success:
213+
print(f"Found {len(rows)} rows with value >= 100:")
214+
for row in rows:
215+
print(f"- {row.name} (ID: {row.id})")
216+
```
217+
*(See `sync.py` and `a_sync.py` docstrings or the full README examples from previous interactions for more detailed usage)*
218+
219+
### Testing
220+
Ensure development dependencies are installed (`uv pip install -r dev_requirements.txt` or `pip install -r dev_requirements.txt`).
221+
222+
Run the test suite using pytest:
223+
224+
```bash
225+
python -m pytest
226+
```
227+
228+
This will execute all tests in the `tests/` directory and provide coverage information based on the `pytest.ini` or `pyproject.toml` configuration.
229+
230+
---
231+
232+
## Project Roadmap
233+
234+
- [x] **Alpha Release**: Initial working version with core CRUD functions.
235+
- [x] **Testing**: Achieve 100% test coverage via Pytest.
236+
- [x] **CI/CD**: Implement GitHub Actions for automated testing, build, and release.
237+
- [x] **Beta Release**: Refine features based on initial testing and usage.
238+
- [ ] **Community Feedback**: Solicit feedback from users.
239+
- [ ] **360 Development Review**: Comprehensive internal review of code, docs, and tests.
240+
- [ ] **Official 1.0 Release**: Stable release suitable for production use.
241+
242+
---
243+
244+
## Contributing
245+
246+
Contributions are welcome! Please feel free to submit issues, feature requests, or pull requests.
247+
248+
- **💬 [Join the Discussions](https://github.com/fsecada01/SQLModel-CRUD-Utilities/discussions)**: Share your insights, provide feedback, or ask questions.
249+
- **🐛 [Report Issues](https://github.com/fsecada01/SQLModel-CRUD-Utilities/issues)**: Submit bugs found or log feature requests for the `sqlmodel_crud_utils` project.
250+
- **💡 [Submit Pull Requests](https://github.com/fsecada01/SQLModel-CRUD-Utilities/blob/main/CONTRIBUTING.md)**: Review open PRs, and submit your own PRs.
251+
<details closed>
252+
<summary>Contributing Guidelines</summary>
253+
254+
1. **Fork the Repository**: Start by forking the project repository to your GitHub account.
255+
2. **Clone Locally**: Clone the forked repository to your local machine.
256+
```bash
257+
git clone https://github.com/fsecada01/SQLModel-CRUD-Utilities.git
258+
```
259+
3. **Create a New Branch**: Always work on a new branch for your changes.
260+
```bash
261+
git checkout -b feature/your-new-feature
262+
```
263+
4. **Make Your Changes**: Implement your feature or bug fix. Add tests!
264+
5. **Test Your Changes**: Run `pytest` to ensure all tests pass.
265+
6. **Format and Lint**: Ensure code follows project standards (e.g., using `black`, `ruff`, `pre-commit`).
266+
7. **Commit Your Changes**: Commit with a clear and concise message.
267+
```bash
268+
git commit -m "feat: Implement the new feature."
269+
```
270+
8. **Push to GitHub**: Push the changes to your forked repository.
271+
```bash
272+
git push origin feature/your-new-feature
273+
```
274+
9. **Submit a Pull Request**: Create a PR against the main branch of the original repository. Clearly describe your changes.
275+
10. **Review**: Wait for code review and address any feedback.
276+
277+
</details>
278+
279+
<details closed>
280+
<summary>Contributor Graph</summary>
281+
<br>
282+
<p align="left">
283+
<!-- Replace YOUR_USERNAME -->
284+
<a href="https://github.com/YOUR_USERNAME/sqlmodel-crud-utils/graphs/contributors">
285+
<img src="https://contrib.rocks/image?repo=YOUR_USERNAME/sqlmodel-crud-utils">
286+
</a>
287+
</p>
288+
</details>
289+
290+
---
291+
292+
## License
293+
294+
This project is protected under the **MIT License**. For more details, refer to the LICENSE file. *(Ensure a LICENSE file with the MIT text exists in your repository)*
295+
296+
---
297+
298+
## Acknowledgments
299+
300+
- inspiration drawn from the need to streamline CRUD operations across multiple projects utilizing SQLModel.
301+
- Built upon the excellent foundations provided by SQLModel and SQLAlchemy.
302+
- Utilizes Loguru for logging and Factory Boy for test data generation.
303+
304+
---

0 commit comments

Comments
 (0)