diff --git a/docs/usage/crud.md b/docs/usage/crud.md index 6c3e981..548f392 100644 --- a/docs/usage/crud.md +++ b/docs/usage/crud.md @@ -35,6 +35,53 @@ Define your SQLAlchemy models and Pydantic schemas for data representation. --8<-- ``` + --- + + ??? example "`customer/model.py`" + + ```python + --8<-- + fastcrud/examples/customer/model.py:imports + fastcrud/examples/customer/model.py:model + --8<-- + ``` + + ??? example "`customer/schemas.py`" + + ```python + --8<-- + fastcrud/examples/customer/schemas.py:imports + fastcrud/examples/customer/schemas.py:readschema + --8<-- + ``` + + ??? example "`product/model.py`" + + ```python + --8<-- + fastcrud/examples/product/model.py:imports + fastcrud/examples/product/model.py:model + --8<-- + ``` + + ??? example "`order/model.py`" + + ```python + --8<-- + fastcrud/examples/order/model.py:imports + fastcrud/examples/order/model.py:model + --8<-- + ``` + + ??? example "`order/schemas.py`" + + ```python + --8<-- + fastcrud/examples/order/schemas.py:imports + fastcrud/examples/order/schemas.py:readschema + --8<-- + ``` + ### Step 2: Initialize FastCRUD Create a `FastCRUD` instance for your model to handle CRUD operations. @@ -44,6 +91,7 @@ from fastcrud import FastCRUD # Creating a FastCRUD instance item_crud = FastCRUD(Item) +order_crud = FastCRUD(Order) ``` ### Step 3: Pick your Method @@ -281,14 +329,14 @@ get_joined( ``` **Purpose**: To fetch a single record with one or multiple joins on other models. -**Usage Example**: Fetches order details for a specific order by joining with the `Customer` table, selecting specific columns as defined in `OrderSchema` and `CustomerSchema`. +**Usage Example**: Fetches order details for a specific order by joining with the `Customer` table, selecting specific columns as defined in `ReadOrderSchema` and `ReadCustomerSchema`. ```python order_details = await order_crud.get_joined( db, + schema_to_select=ReadOrderSchema, join_model=Customer, - schema_to_select=OrderSchema, - join_schema_to_select=CustomerSchema, + join_schema_to_select=ReadCustomerSchema, id=order_id, ) ``` @@ -325,9 +373,9 @@ get_multi_joined( ```python orders = await order_crud.get_multi_joined( db, - schema_to_select=OrderSchema, + schema_to_select=ReadOrderSchema, join_model=Customer, - join_schema_to_select=CustomerSchema, + join_schema_to_select=ReadCustomerSchema, offset=0, limit=5, ) diff --git a/fastcrud/crud/fast_crud.py b/fastcrud/crud/fast_crud.py index 5528d10..521b355 100644 --- a/fastcrud/crud/fast_crud.py +++ b/fastcrud/crud/fast_crud.py @@ -104,6 +104,51 @@ class FastCRUD( Soft deletes a record if it has an `"is_deleted"` attribute (or other attribute as defined by `is_deleted_column`); otherwise, performs a hard delete. Examples: + ??? example "`customer/model.py`" + + ```python + --8<-- + fastcrud/examples/customer/model.py:imports + fastcrud/examples/customer/model.py:model + --8<-- + ``` + + ??? example "`product/model.py`" + + ```python + --8<-- + fastcrud/examples/product/model.py:imports + fastcrud/examples/product/model.py:model + --8<-- + ``` + + ??? example "`product/schemas.py`" + + ```python + --8<-- + fastcrud/examples/product/schemas.py:imports + fastcrud/examples/product/schemas.py:readschema + --8<-- + ``` + + ??? example "`order/model.py`" + + ```python + --8<-- + fastcrud/examples/order/model.py:imports + fastcrud/examples/order/model.py:model + --8<-- + ``` + + ??? example "`order/schemas.py`" + + ```python + --8<-- + fastcrud/examples/order/schemas.py:imports + fastcrud/examples/order/schemas.py:readschema + --8<-- + ``` + Example 1: Basic Usage ---------------------- Create a FastCRUD instance for a `User` model and perform basic CRUD operations. @@ -129,7 +174,9 @@ class FastCRUD( Example 2: Advanced Filtering and Pagination -------------------------------------------- + Use advanced filtering, sorting, and pagination for fetching records. + ```python product_crud = FastCRUD(Product) products = await product_crud.get_multi( @@ -143,15 +190,17 @@ class FastCRUD( Example 3: Join Operations with Custom Schemas ---------------------------------------------- + Perform join operations between two models using custom schemas for selection. + ```python order_crud = FastCRUD(Order) orders = await order_crud.get_multi_joined( db, - schema_to_select=OrderReadSchema, + schema_to_select=ReadOrderSchema, join_model=Product, join_prefix="product_", - join_schema_to_select=ProductReadSchema, + join_schema_to_select=ReadProductSchema, offset=0, limit=5, ) diff --git a/fastcrud/endpoint/crud_router.py b/fastcrud/endpoint/crud_router.py index c685dcd..ffca52f 100644 --- a/fastcrud/endpoint/crud_router.py +++ b/fastcrud/endpoint/crud_router.py @@ -106,6 +106,71 @@ def crud_router( --8<-- ``` + --- + + ??? example "`customer/model.py`" + + ```python + --8<-- + fastcrud/examples/customer/model.py:imports + fastcrud/examples/customer/model.py:model + --8<-- + ``` + + ??? example "`customer/schemas.py`" + + ```python + --8<-- + fastcrud/examples/customer/schemas.py:imports + fastcrud/examples/customer/schemas.py:createschema + fastcrud/examples/customer/schemas.py:readschema + fastcrud/examples/customer/schemas.py:updateschema + fastcrud/examples/customer/schemas.py:deleteschema + --8<-- + ``` + + ??? example "`product/model.py`" + + ```python + --8<-- + fastcrud/examples/product/model.py:imports + fastcrud/examples/product/model.py:model + --8<-- + ``` + + ??? example "`product/schemas.py`" + + ```python + --8<-- + fastcrud/examples/product/schemas.py:imports + fastcrud/examples/product/schemas.py:createschema + fastcrud/examples/product/schemas.py:readschema + fastcrud/examples/product/schemas.py:updateschema + fastcrud/examples/product/schemas.py:deleteschema + --8<-- + ``` + + ??? example "`order/model.py`" + + ```python + --8<-- + fastcrud/examples/order/model.py:imports + fastcrud/examples/order/model.py:model + --8<-- + ``` + + ??? example "`order/schemas.py`" + + ```python + --8<-- + fastcrud/examples/order/schemas.py:imports + fastcrud/examples/order/schemas.py:createschema + fastcrud/examples/order/schemas.py:readschema + fastcrud/examples/order/schemas.py:updateschema + fastcrud/examples/order/schemas.py:deleteschema + --8<-- + ``` + ```python mymodel_router = crud_router( session=async_session, @@ -137,9 +202,9 @@ def get_current_user(token: str = Depends(oauth2_scheme)): Adding Delete Endpoints: ```python - router = crud_router( + product_router = crud_router( session=async_session, - model=ProductModel, + model=Product, create_schema=CreateProductSchema, update_schema=UpdateProductSchema, delete_schema=DeleteProductSchema, @@ -150,12 +215,19 @@ def get_current_user(token: str = Depends(oauth2_scheme)): Customizing Path and Tags: ```python - router = crud_router( + OrderCRUD = FastCRUD[ + Order, + CreateOrderSchema, + UpdateOrderSchema, + UpdateOrderSchema, + DeleteOrderSchema, + ] + order_router = crud_router( session=async_session, - model=OrderModel, + model=Order, create_schema=CreateOrderSchema, update_schema=UpdateOrderSchema, - crud=CRUDOrderModel(OrderModel), + crud=OrderCRUD(Order), path="/orders", tags=["Orders", "Sales"], ) @@ -163,22 +235,36 @@ def get_current_user(token: str = Depends(oauth2_scheme)): Integrating Multiple Models: ```python + ProductCRUD = FastCRUD[ + Product, + CreateProductSchema, + UpdateProductSchema, + UpdateProductSchema, + DeleteProductSchema, + ] product_router = crud_router( session=async_session, - model=ProductModel, + model=Product, create_schema=CreateProductSchema, update_schema=UpdateProductSchema, - crud=CRUDProductModel(ProductModel), + crud=ProductCRUD(Product), path="/products", tags=["Inventory"], ) + CustomerCRUD = FastCRUD[ + Customer, + CreateCustomerSchema, + UpdateCustomerSchema, + UpdateCustomerSchema, + DeleteCustomerSchema, + ] customer_router = crud_router( session=async_session, - model=CustomerModel, + model=Customer, create_schema=CreateCustomerSchema, update_schema=UpdateCustomerSchema, - crud=CRUDCustomerModel(CustomerModel), + crud=CustomerCRUD(Customer), path="/customers", tags=["CRM"], ) diff --git a/fastcrud/examples/customer/model.py b/fastcrud/examples/customer/model.py new file mode 100644 index 0000000..23a4068 --- /dev/null +++ b/fastcrud/examples/customer/model.py @@ -0,0 +1,18 @@ +# --8<-- [start:imports] +from sqlalchemy import Column, Integer, String +from sqlalchemy.orm import DeclarativeBase + + +class Base(DeclarativeBase): + pass + + +# --8<-- [end:imports] +# --8<-- [start:model] +class Customer(Base): + __tablename__ = "customer" + id = Column(Integer, primary_key=True) + name = Column(String) + + +# --8<-- [end:model] diff --git a/fastcrud/examples/customer/schemas.py b/fastcrud/examples/customer/schemas.py new file mode 100644 index 0000000..8aec8e7 --- /dev/null +++ b/fastcrud/examples/customer/schemas.py @@ -0,0 +1,32 @@ +# --8<-- [start:imports] +from pydantic import BaseModel + + +# --8<-- [end:imports] +# --8<-- [start:schemas] +# --8<-- [start:createschema] +class CreateCustomerSchema(BaseModel): + name: str | None = None + + +# --8<-- [end:createschema] +# --8<-- [start:readschema] +class ReadCustomerSchema(BaseModel): + id: int + name: str | None = None + + +# --8<-- [end:readschema] +# --8<-- [start:updateschema] +class UpdateCustomerSchema(BaseModel): + name: str | None = None + + +# --8<-- [end:updateschema] +# --8<-- [start:deleteschema] +class DeleteCustomerSchema(BaseModel): + pass + + +# --8<-- [end:deleteschema] +# --8<-- [end:schemas] diff --git a/fastcrud/examples/order/model.py b/fastcrud/examples/order/model.py new file mode 100644 index 0000000..e96c12c --- /dev/null +++ b/fastcrud/examples/order/model.py @@ -0,0 +1,22 @@ +# --8<-- [start:imports] +from sqlalchemy import Column, ForeignKey, Integer +from sqlalchemy.orm import DeclarativeBase + + +class Base(DeclarativeBase): + pass + + +# --8<-- [end:imports] + + +# --8<-- [start:model] +class Order(Base): + __tablename__ = "order" + id = Column(Integer, primary_key=True) + customer_id = Column(Integer, ForeignKey("customer.id")) + product_id = Column(Integer, ForeignKey("product.id")) + quantity = Column(Integer) + + +# --8<-- [end:model] diff --git a/fastcrud/examples/order/schemas.py b/fastcrud/examples/order/schemas.py new file mode 100644 index 0000000..1082294 --- /dev/null +++ b/fastcrud/examples/order/schemas.py @@ -0,0 +1,38 @@ +# --8<-- [start:imports] +from pydantic import BaseModel + + +# --8<-- [end:imports] +# --8<-- [start:schemas] +# --8<-- [start:createschema] +class CreateOrderSchema(BaseModel): + customer_id: int | None = None + product_id: int | None = None + quantity: int | None = None + + +# --8<-- [end:createschema] +# --8<-- [start:readschema] +class ReadOrderSchema(BaseModel): + id: int + customer_id: int | None = None + product_id: int | None = None + quantity: int | None = None + + +# --8<-- [end:readschema] +# --8<-- [start:updateschema] +class UpdateOrderSchema(BaseModel): + customer_id: int | None = None + product_id: int | None = None + quantity: int | None = None + + +# --8<-- [end:updateschema] +# --8<-- [start:deleteschema] +class DeleteOrderSchema(BaseModel): + pass + + +# --8<-- [end:deleteschema] +# --8<-- [end:schemas] diff --git a/fastcrud/examples/product/model.py b/fastcrud/examples/product/model.py new file mode 100644 index 0000000..b103dcb --- /dev/null +++ b/fastcrud/examples/product/model.py @@ -0,0 +1,19 @@ +# --8<-- [start:imports] +from sqlalchemy import Column, Integer, Numeric, String +from sqlalchemy.orm import DeclarativeBase + + +class Base(DeclarativeBase): + pass + + +# --8<-- [end:imports] +# --8<-- [start:model] +class Product(Base): + __tablename__ = "product" + id = Column(Integer, primary_key=True) + name = Column(String) + price = Column(Numeric) + + +# --8<-- [end:model] diff --git a/fastcrud/examples/product/schemas.py b/fastcrud/examples/product/schemas.py new file mode 100644 index 0000000..f67cc56 --- /dev/null +++ b/fastcrud/examples/product/schemas.py @@ -0,0 +1,35 @@ +# --8<-- [start:imports] +from pydantic import BaseModel + + +# --8<-- [end:imports] +# --8<-- [start:schemas] +# --8<-- [start:createschema] +class CreateProductSchema(BaseModel): + name: str | None = None + price: float | None = None + + +# --8<-- [end:createschema] +# --8<-- [start:readschema] +class ReadProductSchema(BaseModel): + id: int + name: str | None = None + price: float | None = None + + +# --8<-- [end:readschema] +# --8<-- [start:updateschema] +class UpdateProductSchema(BaseModel): + name: str | None = None + price: float | None = None + + +# --8<-- [end:updateschema] +# --8<-- [start:deleteschema] +class DeleteProductSchema(BaseModel): + pass + + +# --8<-- [end:deleteschema] +# --8<-- [end:schemas]