Skip to content

Commit

Permalink
✨ deleted support
Browse files Browse the repository at this point in the history
  • Loading branch information
juftin committed Aug 23, 2023
1 parent 17a9c1f commit fe89b2d
Show file tree
Hide file tree
Showing 8 changed files with 60 additions and 22 deletions.
17 changes: 13 additions & 4 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,19 @@ detached = true
compile = "pip-compile {args:} --generate-hashes --output-file requirements.txt"
update = "compile --upgrade"

[tool.hatch.envs.docs]
dependencies = [
"mkdocs~=1.5.2",
"mkdocs-material~=9.1.21",
"mkdocstrings~=0.22.0",
]
detached = true

[tool.hatch.envs.docs.scripts]
build = ["mkdocs build --clean --strict"]
deploy = ["mkdocs gh-deploy {args:}"]
serve = ["mkdocs serve --dev-addr localhost:8080 --livereload"]

[tool.hatch.envs.lint]
dependencies = [
"black~=23.7.0",
Expand Down Expand Up @@ -183,10 +196,6 @@ select = [
"YTT"
]
target-version = "py38"
unfixable = [
# Don't touch unused imports
"F401"
]

[tool.ruff.flake8-tidy-imports]
ban-relative-imports = "all"
Expand Down
4 changes: 2 additions & 2 deletions zoo/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
from fastapi import FastAPI

from zoo._version import __application__, __description__, __version__
from zoo.application.animals import animals_router
from zoo.application.utils import utils_router
from zoo.backend.animals import animals_router
from zoo.backend.utils import utils_router
from zoo.config import config
from zoo.db import init_db

Expand Down
File renamed without changes.
19 changes: 13 additions & 6 deletions zoo/application/animals.py → zoo/backend/animals.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from typing import List, Optional

from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy import func
from sqlalchemy.ext.asyncio import AsyncSession
from sqlmodel import select

Expand All @@ -19,12 +20,16 @@

@animals_router.get("/animals", response_model=List[AnimalsRead])
async def get_animals(
offset: int = 0, limit: int = Query(default=100, le=100), session: AsyncSession = Depends(get_session)
offset: int = 0,
limit: int = Query(default=100, le=100),
session: AsyncSession = Depends(get_session),
) -> List[Animals]:
"""
Get animals from the database
"""
result = await session.execute(select(Animals).offset(offset).limit(limit))
result = await session.execute(
select(Animals).where(Animals.deleted_at.is_(None)).offset(offset).limit(limit) # type: ignore[union-attr]
)
animals: List[Animals] = result.scalars().all()
return animals

Expand All @@ -47,7 +52,7 @@ async def get_animal(animal_id: int, session: AsyncSession = Depends(get_session
Get an animal from the database
"""
animal: Optional[Animals] = await session.get(Animals, animal_id)
if animal is None:
if animal is None or animal.deleted_at is not None:
raise HTTPException(status_code=404, detail=f"Error: Animal not found - ID: {animal_id}")
return animal

Expand All @@ -58,10 +63,12 @@ async def delete_animal(animal_id: int, session: AsyncSession = Depends(get_sess
Delete an animal from the database
"""
animal: Optional[Animals] = await session.get(Animals, animal_id)
if animal is None:
if animal is None or animal.deleted_at is not None:
raise HTTPException(status_code=404, detail=f"Error: Animal not found - ID # {animal_id}")
await session.delete(animal)
animal.deleted_at = func.CURRENT_TIMESTAMP() # type: ignore[assignment]
session.add(animal)
await session.commit()
await session.refresh(animal)
return animal


Expand All @@ -71,7 +78,7 @@ async def update_animal(animal_id: int, animal: AnimalsUpdate, session: AsyncSes
Update an animal in the database
"""
db_animal: Optional[Animals] = await session.get(Animals, animal_id)
if db_animal is None:
if db_animal is None or db_animal.deleted_at is not None:
raise HTTPException(status_code=404, detail=f"Error: Animal not found - ID: {animal_id}")
for field, value in animal.dict(exclude_unset=True).items():
if value is not None:
Expand Down
File renamed without changes.
9 changes: 6 additions & 3 deletions zoo/db.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

config = ZooSettings()
engine = create_async_engine(config.connection_string, echo=True, future=True)
async_session = sessionmaker(engine, class_=AsyncSession, autocommit=False, expire_on_commit=False, autoflush=False)


@listens_for(Animals.__table__, "after_create") # type: ignore[attr-defined]
Expand All @@ -42,6 +43,8 @@ async def get_session() -> AsyncGenerator[AsyncSession, None]:
Used by FastAPI Depends
"""
async_session = sessionmaker(engine, class_=AsyncSession, autocommit=False, expire_on_commit=False)
async with async_session() as session:
yield session
try:
async with async_session() as session:
yield session
finally:
await session.close()
16 changes: 11 additions & 5 deletions zoo/models/animals.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,15 @@
from sqlalchemy.future import Connection
from sqlmodel import Field, SQLModel

from zoo.models.base import CreatedModifiedMixin, OptionalIdMixin, RequiredIdMixin
from zoo.models.base import CreatedModifiedMixin, DeletedMixin, OptionalIdMixin, RequiredIdMixin

_animal_example = {
"name": "Lion",
"description": "Ferocious kitty",
"species": "Panthera leo",
"created": "2021-01-01T00:00:00.000000",
"modified": "2021-01-02T09:12:34.567890",
"deleted_at": None,
"created_at": "2021-01-01T00:00:00.000000",
"modified_at": "2021-01-02T09:12:34.567890",
}


Expand All @@ -42,7 +43,12 @@ class Config:
schema_extra: ClassVar[Dict[str, Any]] = {"examples": [_animal_example]}


class AnimalsRead(AnimalsBase, RequiredIdMixin, CreatedModifiedMixin):
class AnimalsRead(
DeletedMixin,
CreatedModifiedMixin,
AnimalsBase,
RequiredIdMixin,
):
"""
Animals model: read
"""
Expand All @@ -55,7 +61,7 @@ class Config:
schema_extra: ClassVar[Dict[str, Any]] = {"examples": [{"id": 1, **_animal_example}]}


class Animals(AnimalsBase, CreatedModifiedMixin, OptionalIdMixin, table=True):
class Animals(DeletedMixin, CreatedModifiedMixin, AnimalsBase, OptionalIdMixin, table=True):
"""
Animals model: database table
"""
Expand Down
17 changes: 15 additions & 2 deletions zoo/models/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,17 +34,30 @@ class CreatedModifiedMixin(SQLModel):
Created and modified mixin
"""

created: datetime.datetime = Field(
created_at: datetime.datetime = Field(
default_factory=datetime.datetime.utcnow,
nullable=False,
description="The date and time the record was created",
sa_column=Column(DateTime(timezone=True), server_default=func.CURRENT_TIMESTAMP()),
)
modified: datetime.datetime = Field(
modified_at: datetime.datetime = Field(
default_factory=datetime.datetime.utcnow,
nullable=False,
description="The date and time the record was last modified",
sa_column=Column(
DateTime(timezone=True), server_default=func.CURRENT_TIMESTAMP(), onupdate=func.CURRENT_TIMESTAMP()
),
)


class DeletedMixin(SQLModel):
"""
Deleted mixin
"""

deleted_at: Optional[datetime.datetime] = Field(
default=None,
nullable=True,
description="The date and time the record was deleted",
sa_column=Column(DateTime(timezone=True), default=None, nullable=True, sort_order=-1),
)

0 comments on commit fe89b2d

Please sign in to comment.