Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Crud enhancement #14

Merged
merged 7 commits into from
Feb 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 70 additions & 0 deletions docs/advanced/crud.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@

# Advanced Use of FastCRUD

FastCRUD offers a flexible and powerful approach to handling CRUD operations in FastAPI applications, leveraging the SQLAlchemy ORM. Beyond basic CRUD functionality, FastCRUD provides advanced features like `allow_multiple` for updates and deletes, and support for advanced filters (e.g., less than, greater than). These features enable more complex and fine-grained data manipulation and querying capabilities.

## Allow Multiple Updates and Deletes

One of FastCRUD's advanced features is the ability to update or delete multiple records at once based on specified conditions. This is particularly useful for batch operations where you need to modify or remove several records that match certain criteria.

### Updating Multiple Records

To update multiple records, you can set the `allow_multiple=True` parameter in the `update` method. This allows FastCRUD to apply the update to all records matching the given filters.

```python
# Assuming setup for FastCRUD instance `item_crud` and SQLAlchemy async session `db`

# Update all items priced below $10 to a new price
await item_crud.update(
db=db,
object={"price": 9.99},
allow_multiple=True,
price__lt=10
)
```

### Deleting Multiple Records

Similarly, you can delete multiple records by using the `allow_multiple=True` parameter in the `delete` or `db_delete` method, depending on whether you're performing a soft or hard delete.

```python
# Soft delete all items not sold in the last year
await item_crud.delete(
db=db,
allow_multiple=True,
last_sold__lt=datetime.datetime.now() - datetime.timedelta(days=365)
)
```

## Advanced Filters

FastCRUD supports advanced filtering options, allowing you to query records using operators such as greater than (`__gt`), less than (`__lt`), and their inclusive counterparts (`__gte`, `__lte`). These filters can be used in any method that retrieves or operates on records, including `get`, `get_multi`, `exists`, `count`, `update`, and `delete`.

### Using Advanced Filters

The following examples demonstrate how to use advanced filters for querying and manipulating data:

#### Fetching Records with Advanced Filters

```python
# Fetch items priced between $5 and $20
items = await item_crud.get_multi(
db=db,
price__gte=5,
price__lte=20
)
```

#### Counting Records

```python
# Count items added in the last month
item_count = await item_crud.count(
db=db,
added_at__gte=datetime.datetime.now() - datetime.timedelta(days=30)
)
```

## Conclusion

The advanced features of FastCRUD, such as `allow_multiple` and support for advanced filters, empower developers to efficiently manage database records with complex conditions. By leveraging these capabilities, you can build more dynamic, robust, and scalable FastAPI applications that effectively interact with your data model.
64 changes: 64 additions & 0 deletions docs/advanced/endpoint.md
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,70 @@ my_router = crud_router(
app.include_router(my_router)
```

## Custom Soft Delete

To implement custom soft delete columns using `EndpointCreator` and `crud_router` in FastCRUD, you need to specify the names of the columns used for indicating deletion status and the deletion timestamp in your model. FastCRUD provides flexibility in handling soft deletes by allowing you to configure these column names directly when setting up CRUD operations or API endpoints.

Here's how to specify custom soft delete columns when utilizing `EndpointCreator` and `crud_router`:

### Defining Models with Custom Soft Delete Columns

First, ensure your SQLAlchemy model is equipped with the custom soft delete columns. Here's an example model with custom columns for soft deletion:

```python
from sqlalchemy import Column, Integer, String, DateTime, Boolean
from sqlalchemy.ext.declarative import declarative_base
from datetime import datetime

Base = declarative_base()

class MyModel(Base):
__tablename__ = 'my_model'
id = Column(Integer, primary_key=True)
name = Column(String)
archived = Column(Boolean, default=False) # Custom soft delete column
archived_at = Column(DateTime) # Custom timestamp column for soft delete
```

### Using `EndpointCreator` and `crud_router` with Custom Soft Delete Columns

When initializing `crud_router` or creating a custom `EndpointCreator`, you can pass the names of your custom soft delete columns through the `FastCRUD` initialization. This informs FastCRUD which columns to check and update for soft deletion operations.

Here's an example of using `crud_router` with custom soft delete columns:

```python
from fastapi import FastAPI
from fastcrud import FastCRUD, crud_router
from sqlalchemy.ext.asyncio import AsyncSession

app = FastAPI()

# Assuming async_session is your AsyncSession generator
# and MyModel is your SQLAlchemy model

# Initialize FastCRUD with custom soft delete columns
my_model_crud = FastCRUD(MyModel,
is_deleted_column='archived', # Custom 'is_deleted' column name
deleted_at_column='archived_at' # Custom 'deleted_at' column name
)

# Setup CRUD router with the FastCRUD instance
app.include_router(crud_router(
session=async_session,
model=MyModel,
crud=my_model_crud,
create_schema=CreateMyModelSchema,
update_schema=UpdateMyModelSchema,
delete_schema=DeleteMyModelSchema,
path="/mymodel",
tags=["MyModel"]
))
```

This setup ensures that the soft delete functionality within your application utilizes the `archived` and `archived_at` columns for marking records as deleted, rather than the default `is_deleted` and `deleted_at` fields.

By specifying custom column names for soft deletion, you can adapt FastCRUD to fit the design of your database models, providing a flexible solution for handling deleted records in a way that best suits your application's needs.

## Conclusion

The `EndpointCreator` class in FastCRUD offers flexibility and control over CRUD operations and custom endpoint creation. By extending this class or using the `included_methods` and `deleted_methods` parameters, you can tailor your API's functionality to your specific requirements, ensuring a more customizable and streamlined experience.
28 changes: 28 additions & 0 deletions docs/advanced/overview.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Advanced Usage Overview

The Advanced section of our documentation delves into the sophisticated capabilities and features of our application, tailored for users looking to leverage advanced functionalities. This part of our guide aims to unlock deeper insights and efficiencies through more complex use cases and configurations.

## Key Topics

### 1. Advanced Filtering and Searching
Explore how to implement advanced filtering and searching capabilities in your application. This guide covers the use of comparison operators (such as greater than, less than, etc.), pattern matching, and more to perform complex queries.

- [Advanced Filtering Guide](crud.md#advanced-filters)

### 2. Bulk Operations and Batch Processing
Learn how to efficiently handle bulk operations and batch processing. This section provides insights into performing mass updates, deletes, and inserts, optimizing performance for large datasets.

- [Bulk Operations Guide](crud.md#allow-multiple-updates-and-deletes)

### 3. Soft Delete Mechanisms and Strategies
Understand the implementation of soft delete mechanisms within our application. This guide covers configuring and using custom columns for soft deletes, restoring deleted records, and filtering queries to exclude soft-deleted entries.

- [Soft Delete Strategies Guide](endpoint.md#custom-soft-delete)

### 4. Advanced Use of EndpointCreator and crud_router
This topic extends the use of `EndpointCreator` and `crud_router` for advanced endpoint management, including creating custom routes, selective method exposure, and integrating soft delete functionalities.

- [Advanced Endpoint Management Guide](endpoint.md#advanced-use-of-endpointcreator)

## Prerequisites
Advanced usage assumes a solid understanding of the basic features and functionalities of our application. Knowledge of FastAPI, SQLAlchemy, and Pydantic is highly recommended to fully grasp the concepts discussed.
9 changes: 7 additions & 2 deletions docs/usage/crud.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,9 @@ new_item = await item_crud.create(db, ItemCreateSchema(name="New Item"))
get(
db: AsyncSession,
schema_to_select: Optional[type[BaseModel]] = None,
return_as_model: bool = False,
**kwargs: Any
) -> Optional[dict]
) -> Optional[Union[dict, BaseModel]]
```

**Purpose**: To fetch a single record based on filters, with an option to select specific columns using a Pydantic schema.
Expand Down Expand Up @@ -136,6 +137,7 @@ items = await item_crud.get_multi(db, offset=10, limit=5)
update(
db: AsyncSession,
object: Union[UpdateSchemaType, dict[str, Any]],
allow_multiple: bool = False,
**kwargs: Any
) -> None
```
Expand All @@ -153,6 +155,7 @@ await item_crud.update(db, ItemUpdateSchema(description="Updated"), id=item_id)
delete(
db: AsyncSession,
db_row: Optional[Row] = None,
allow_multiple: bool = False,
**kwargs: Any
) -> None
```
Expand All @@ -169,6 +172,7 @@ await item_crud.delete(db, id=item_id)
```python
db_delete(
db: AsyncSession,
allow_multiple: bool = False,
**kwargs: Any
) -> None
```
Expand Down Expand Up @@ -217,7 +221,8 @@ get_joined(
join_on: Optional[Union[Join, None]] = None,
schema_to_select: Optional[type[BaseModel]] = None,
join_schema_to_select: Optional[type[BaseModel]] = None,
join_type: str = "left", **kwargs: Any
join_type: str = "left",
**kwargs: Any
) -> Optional[dict[str, Any]]
```

Expand Down
Loading
Loading