mirror of
https://github.com/d3vyce/fastapi-toolsets.git
synced 2026-03-02 17:30:48 +01:00
docs: add migration + fix icon
This commit is contained in:
137
docs/migration/v2.md
Normal file
137
docs/migration/v2.md
Normal file
@@ -0,0 +1,137 @@
|
||||
# Migrating to v2.0
|
||||
|
||||
This page covers every breaking change introduced in **v2.0** and the steps required to update your code.
|
||||
|
||||
---
|
||||
|
||||
## CRUD
|
||||
|
||||
### `schema` is now required in `offset_paginate()` and `cursor_paginate()`
|
||||
|
||||
Calls that omit `schema` will now raise a `TypeError` at runtime.
|
||||
|
||||
Previously `schema` was optional; omitting it returned raw SQLAlchemy model instances inside the response. It is now a required keyword argument and the response always contains serialized schema instances.
|
||||
|
||||
=== "Before (`v1`)"
|
||||
|
||||
```python
|
||||
# schema omitted — returned raw model instances
|
||||
result = await UserCrud.offset_paginate(session, page=1)
|
||||
result = await UserCrud.cursor_paginate(session, cursor=token)
|
||||
```
|
||||
|
||||
=== "Now (`v2`)"
|
||||
|
||||
```python
|
||||
result = await UserCrud.offset_paginate(session, page=1, schema=UserRead)
|
||||
result = await UserCrud.cursor_paginate(session, cursor=token, schema=UserRead)
|
||||
```
|
||||
|
||||
### `as_response` removed from `create()`, `get()`, and `update()`
|
||||
|
||||
Passing `as_response` to these methods will raise a `TypeError` at runtime.
|
||||
|
||||
The `as_response=True` shorthand is replaced by passing a `schema` directly. The return value is a `Response[schema]` when `schema` is provided, or the raw model instance when it is not.
|
||||
|
||||
=== "Before (`v1`)"
|
||||
|
||||
```python
|
||||
user = await UserCrud.create(session, data, as_response=True)
|
||||
user = await UserCrud.get(session, filters, as_response=True)
|
||||
user = await UserCrud.update(session, data, filters, as_response=True)
|
||||
```
|
||||
|
||||
=== "Now (`v2`)"
|
||||
|
||||
```python
|
||||
user = await UserCrud.create(session, data, schema=UserRead)
|
||||
user = await UserCrud.get(session, filters, schema=UserRead)
|
||||
user = await UserCrud.update(session, data, filters, schema=UserRead)
|
||||
```
|
||||
|
||||
### `delete()`: `as_response` renamed and return type changed
|
||||
|
||||
`as_response` is gone, and the plain (non-response) call no longer returns `True`.
|
||||
|
||||
Two changes were made to `delete()`:
|
||||
|
||||
1. The `as_response` parameter is renamed to `return_response`.
|
||||
2. When called without `return_response=True`, the method now returns `None` on success instead of `True`.
|
||||
|
||||
=== "Before (`v1`)"
|
||||
|
||||
```python
|
||||
ok = await UserCrud.delete(session, filters)
|
||||
if ok: # True on success
|
||||
...
|
||||
|
||||
response = await UserCrud.delete(session, filters, as_response=True)
|
||||
```
|
||||
|
||||
=== "Now (`v2`)"
|
||||
|
||||
```python
|
||||
await UserCrud.delete(session, filters) # returns None
|
||||
|
||||
response = await UserCrud.delete(session, filters, return_response=True)
|
||||
```
|
||||
|
||||
### `paginate()` alias removed
|
||||
|
||||
Any call to `crud.paginate(...)` will raise `AttributeError` at runtime.
|
||||
|
||||
The `paginate` shorthand was an alias for `offset_paginate`. It has been removed; call `offset_paginate` directly.
|
||||
|
||||
=== "Before (`v1`)"
|
||||
|
||||
```python
|
||||
result = await UserCrud.paginate(session, page=2, items_per_page=20, schema=UserRead)
|
||||
```
|
||||
|
||||
=== "Now (`v2`)"
|
||||
|
||||
```python
|
||||
result = await UserCrud.offset_paginate(session, page=2, items_per_page=20, schema=UserRead)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Exceptions
|
||||
|
||||
### Missing `api_error` raises `TypeError` at class definition time
|
||||
|
||||
Unfinished or stub exception subclasses that previously compiled fine will now fail on import.
|
||||
|
||||
In `v1`, a subclass without `api_error` would only fail when the exception was raised. In `v2`, `__init_subclass__` validates this at class definition time.
|
||||
|
||||
=== "Before (`v1`)"
|
||||
|
||||
```python
|
||||
class MyError(ApiException):
|
||||
pass # fine until raised
|
||||
```
|
||||
|
||||
=== "Now (`v2`)"
|
||||
|
||||
```python
|
||||
class MyError(ApiException):
|
||||
pass # TypeError: MyError must define an 'api_error' class attribute.
|
||||
```
|
||||
|
||||
For shared base classes that are not meant to be raised directly, use `abstract=True`:
|
||||
|
||||
```python
|
||||
class BillingError(ApiException, abstract=True):
|
||||
"""Base for all billing-related errors — not raised directly."""
|
||||
|
||||
class PaymentRequiredError(BillingError):
|
||||
api_error = ApiError(code=402, msg="Payment Required", desc="...", err_code="BILLING-402")
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Schemas
|
||||
|
||||
### `Pagination` alias removed
|
||||
|
||||
`Pagination` was already deprecated in `v1` and is fully removed in `v2`, you now need to use [`OffsetPagination`](../reference/schemas.md#fastapi_toolsets.schemas.OffsetPagination) or [`CursorPagination`](../reference/schemas.md#fastapi_toolsets.schemas.CursorPagination).
|
||||
Reference in New Issue
Block a user