Skip to content

Commit 94b878f

Browse files
authored
Merge pull request #32 from igorbenav/schema_to_select-improvement
schema_to_select now also accepts a list of column names, docs updated
2 parents 7c4e815 + 1b861f9 commit 94b878f

File tree

3 files changed

+26
-27
lines changed

3 files changed

+26
-27
lines changed

README.md

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -33,24 +33,25 @@
3333
## 0. About
3434
**FastAPI boilerplate** creates an extendable async API using FastAPI, Pydantic V2, SQLAlchemy 2.0 and PostgreSQL:
3535
- [`FastAPI`](https://fastapi.tiangolo.com): modern Python web framework for building APIs
36-
- [`Pydantic V2`](https://docs.pydantic.dev/2.4/): the most widely used data validation library for Python, rewritten in Rust [`(5x-50x faster)`](https://docs.pydantic.dev/latest/blog/pydantic-v2-alpha/)
36+
- [`Pydantic V2`](https://docs.pydantic.dev/2.4/): the most widely used data Python validation library, rewritten in Rust [`(5x-50x faster)`](https://docs.pydantic.dev/latest/blog/pydantic-v2-alpha/)
3737
- [`SQLAlchemy 2.0`](https://docs.sqlalchemy.org/en/20/changelog/whatsnew_20.html): Python SQL toolkit and Object Relational Mapper
3838
- [`PostgreSQL`](https://www.postgresql.org): The World's Most Advanced Open Source Relational Database
39-
- [`Redis`](https://redis.io): Open source, in-memory data store used by millions as a database, cache, streaming engine, and message broker
39+
- [`Redis`](https://redis.io): Open source, in-memory data store used by millions as a cache, message broker and more.
4040
- [`ARQ`](https://arq-docs.helpmanual.io) Job queues and RPC in python with asyncio and redis.
4141
- [`Docker Compose`](https://docs.docker.com/compose/) With a single command, create and start all the services from your configuration.
4242

4343
## 1. Features
44-
- Fully async
45-
- Pydantic V2 and SQLAlchemy 2.0
46-
- User authentication with JWT
47-
- Easy redis caching
48-
- Easy client-side caching
49-
- ARQ integration for task queue
50-
- Efficient querying (only queries what's needed)
51-
- Easily extendable
52-
- Flexible
53-
- Easy running with docker compose
44+
- ⚡️ Fully async
45+
- 🚀 Pydantic V2 and SQLAlchemy 2.0
46+
- 🔐 User authentication with JWT
47+
- 🏬 Easy redis caching
48+
- 👜 Easy client-side caching
49+
- 🚦 ARQ integration for task queue
50+
- ⚙️ Efficient querying (only queries what's needed)
51+
- 👮 FastAPI docs behind authentication and hidden based on the environment
52+
- 🦾 Easily extendable
53+
- 🤸‍♂️ Flexible
54+
- 🚚 Easy running with docker compose
5455

5556
### 1.1 To Do
5657
#### API
@@ -64,13 +65,7 @@
6465
#### Features
6566
- [ ] Add a Rate Limiter decorator
6667
- [ ] Add mongoDB support
67-
- [ ] Add support in schema_to_select for dict as well as Pydantic Schema
68-
69-
#### Security
70-
- [x] FastAPI docs behind authentication and hidden based on the environment
71-
72-
#### Structure
73-
- [x] Remove python-decouple in favor of starlette.config
68+
- [x] Add support in schema_to_select for a list of column names
7469

7570
#### Tests
7671
- [ ] Add Ruff linter
@@ -634,7 +629,7 @@ crud_users.db_delete(db=db, username="myusername")
634629
```
635630

636631
#### More Efficient Selecting
637-
For the `get` and `get_multi` methods we have the option to define a `schema_to_select` attribute, which is what actually makes the queries more efficient. When you pass a pydantic schema in `schema_to_select` to the `get` or `get_multi` methods, only the attributes in the schema will be selected.
632+
For the `get` and `get_multi` methods we have the option to define a `schema_to_select` attribute, which is what actually makes the queries more efficient. When you pass a `pydantic schema` (preferred) or a list of the names of the attributes in `schema_to_select` to the `get` or `get_multi` methods, only the attributes in the schema will be selected.
638633
```python
639634
from app.schemas.user import UserRead
640635
# Here it's selecting all of the user's data

src/app/crud/crud_base.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ async def create(
5555
async def get(
5656
self,
5757
db: AsyncSession,
58-
schema_to_select: Type[BaseModel] | None = None,
58+
schema_to_select: Union[Type[BaseModel], List, None] = None,
5959
**kwargs
6060
) -> Row | None:
6161
"""
@@ -65,7 +65,7 @@ async def get(
6565
----------
6666
db : AsyncSession
6767
The SQLAlchemy async session.
68-
schema_to_select : Type[BaseModel] | None, optional
68+
schema_to_select : Union[Type[BaseModel], List, None], optional
6969
Pydantic schema for selecting specific columns. Default is None to select all columns.
7070
kwargs : dict
7171
Filters to apply to the query.
@@ -87,7 +87,7 @@ async def get_multi(
8787
db: AsyncSession,
8888
offset: int = 0,
8989
limit: int = 100,
90-
schema_to_select: Type[BaseModel] | None = None,
90+
schema_to_select: Union[Type[BaseModel], List, None] = None,
9191
**kwargs
9292
) -> List[Row]:
9393
"""
@@ -101,7 +101,7 @@ async def get_multi(
101101
Number of rows to skip before fetching. Default is 0.
102102
limit : int, optional
103103
Maximum number of rows to fetch. Default is 100.
104-
schema_to_select : Type[BaseModel] | None, optional
104+
schema_to_select : Union[Type[BaseModel], List, None], optional
105105
Pydantic schema for selecting specific columns. Default is None to select all columns.
106106
kwargs : dict
107107
Filters to apply to the query.

src/app/crud/helper.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
from typing import Any, List, Type
1+
from typing import Any, List, Type, Union, Dict
22

33
from pydantic import BaseModel
44

55
from app.core.database import Base
66

7-
def _extract_matching_columns_from_schema(model: Type[Base], schema: Type[BaseModel] | None) -> List[Any]:
7+
def _extract_matching_columns_from_schema(model: Type[Base], schema: Union[Type[BaseModel], List, None]) -> List[Any]:
88
"""
99
Retrieves a list of ORM column objects from a SQLAlchemy model that match the field names in a given Pydantic schema.
1010
@@ -22,7 +22,11 @@ def _extract_matching_columns_from_schema(model: Type[Base], schema: Type[BaseMo
2222
"""
2323
column_list = list(model.__table__.columns)
2424
if schema is not None:
25-
schema_fields = schema.model_fields.keys()
25+
if isinstance(schema, list):
26+
schema_fields = schema
27+
else:
28+
schema_fields = schema.model_fields.keys()
29+
2630
column_list = []
2731
for column_name in schema_fields:
2832
if hasattr(model, column_name):

0 commit comments

Comments
 (0)