Skip to content

0.14.0

Compare
Choose a tag to compare
@igorbenav igorbenav released this 29 Jul 04:24
· 95 commits to main since this release
c056ab2

0.14.0 Summary

Added

  • Type-checking support for SQLModel types by @kdcokenny
  • Returning clause to update operations by @feluelle
  • Upsert_multi functionality by @feluelle
  • Simplified endpoint configurations by @JakNowy, streamlining path generation and merging pagination functionalities into a unified _read_items endpoint, promoting more efficient API structure and usage. Details in #105

Improved

  • Comprehensive tests for paginated retrieval of items, maintaining 100% coverage
  • Docker client check before running tests that require Docker by @feluelle

Fixed

  • Vulnerability associated with an outdated cryptography package
  • Return type inconsistency in async session fixtures by @slaarti

Documentation Updates

  • Cleanup of documentation formatting by @slaarti
  • Replacement of the Contributing section in docs with an include to file in repo root by @slaarti
  • Correction of links to advanced filters in docstrings by @slaarti
  • Backfill of docstring fixes across various modules by @slaarti
  • Enhanced filter documentation with new AND and OR clause examples, making complex queries more accessible and understandable.

Models and Schemas Enhancements

  • Introduction of simple and one-off models (Batch 1) by @slaarti
  • Expansion to include models and schemas for Customers, Products, and Orders (Batch 2) by @slaarti

Code Refinements

  • Resolution of missing type specifications in kwargs by @slaarti
  • Collapsed space adjustments for models/schemas in fast_crud.py by @slaarti

Warnings

  • Deprecation Notice: _read_paginated endpoint is set to be deprecated and merged into _read_items. Users are encouraged to transition to the latter, utilizing optional pagination parameters. Full details and usage instructions provided to ensure a smooth transition.
  • Future Changes Alert: Default endpoint names in EndpointCreator are anticipated to be set to empty strings in a forthcoming major release, aligning with simplification efforts. Refer to #67 for more information.

Detailed


Simplified Endpoint Configurations

In an effort to streamline FastCRUD’s API, we have reconfigured endpoint paths to avoid redundancy (great work by @JakNowy). This change allows developers to specify empty strings for endpoint names in the crud_router setup, which prevents the generation of unnecessary // in the paths. The following configurations illustrate how endpoints can now be defined more succinctly:

endpoint_names = {
    "create": "",
    "read": "",
    "update": "",
    "delete": "",
    "db_delete": "",
    "read_multi": "",
    "read_paginated": "get_paginated",
}

Moreover, the _read_paginated logic has been integrated into the _read_items endpoint. This integration means that pagination can now be controlled via page and items_per_page query parameters, offering a unified method for both paginated and non-paginated reads:

  • Paginated read example:
curl -X 'GET' \
  'http://localhost:8000/users/get_multi?page=2&itemsPerPage=10' \
  -H 'accept: application/json'
  • Non-paginated read example:
curl -X 'GET' \
  'http://localhost:8000/users/get_multi?offset=0&limit=100' \
  -H 'accept: application/json'

Warnings

  • Deprecation Warning: The _read_paginated endpoint is slated for deprecation. Developers should transition to using _read_items with the relevant pagination parameters.
  • Configuration Change Alert: In a future major release, default endpoint names in EndpointCreator will be empty strings by default, as discussed in Issue #67.

Advanced Filters Documentation Update

Documentation for advanced filters has been expanded to include comprehensive examples of AND and OR clauses, enhancing the utility and accessibility of complex query constructions.

  • OR clause example:
# Fetch items priced under $5 or above $20
items = await item_crud.get_multi(
    db=db,
    price__or={'lt': 5, 'gt': 20},
)
  • AND clause example:
# Fetch items priced under $20 and over 2 years of warranty
items = await item_crud.get_multi(
    db=db,
    price__lt=20,
    warranty_years__gt=2,
)

Returning Clauses in Update Operations

Description

Users can now retrieve updated records immediately following an update operation. This feature streamlines the process, reducing the need for subsequent retrieval calls and increasing efficiency.

Changes

  • Return Columns: Specify the columns to be returned after the update via the return_columns argument.
  • Schema Selection: Optionally select a Pydantic schema to format the returned data using the schema_to_select argument.
  • Return as Model: Decide if the returned data should be converted into a model using the return_as_model argument.
  • Single or None: Utilize the one_or_none argument to ensure that either a single record is returned or none, in case the conditions do not match any records.

These additions are aligned with existing CRUD API functions, enhancing consistency across the library and making the new features intuitive for users.

Usage Example

Returning Updated Fields

from fastcrud import FastCRUD
from .models.item import Item
from .database import session as db

crud_items = FastCRUD(Item)
updated_item = await crud_items.update(
    db=db,
    object={"price": 9.99},
    price__lt=10,
    return_columns=["price"]
)
# This returns the updated price of the item directly.

Returning Data as a Model

from fastcrud import FastCRUD
from .models.item import Item
from .schemas.item import ItemSchema
from .database import session as db

crud_items = FastCRUD(Item)
updated_item_schema = await crud_items.update(
    db=db,
    object={"price": 9.99},
    price__lt=10,
    schema_to_select=ItemSchema,
    return_as_model=True
)
# This returns the updated item data formatted as an ItemSchema model.

Bulk Upsert Operations with upsert_multi

The upsert_multi method provides the ability to perform bulk upsert operations, which are optimized for different SQL dialects.

Changes

  • Dialect-Optimized SQL: Uses the most efficient SQL commands based on the database's SQL dialect.
  • Support for Multiple Dialects: Includes custom implementations for PostgreSQL, SQLite, and MySQL, with appropriate handling for each's capabilities and limitations.

Usage Example

Upserting Multiple Records

from fastcrud import FastCRUD
from .models.item import Item
from .schemas.item import ItemCreateSchema, ItemSchema
from .database import session as db

crud_items = FastCRUD(Item)
items = await crud_items.upsert_multi(
    db=db,
    instances=[
        ItemCreateSchema(price=9.99),
    ],
    schema_to_select=ItemSchema,
    return_as_model=True,
)
# This will return the upserted data in the form of ItemSchema.

Implementation Details

upsert_multi handles different database dialects:

  • PostgreSQL: Uses ON CONFLICT DO UPDATE.
  • SQLite: Utilizes ON CONFLICT DO UPDATE.
  • MySQL: Implements ON DUPLICATE KEY UPDATE.

Notes

  • MySQL and MariaDB do not support certain advanced features used in other dialects, such as returning values directly after an insert or update operation. This limitation is clearly documented to prevent misuse.

What's Changed

New Contributors

Full Changelog: v0.13.1...v0.14.0

You may also see this in the docs.