Add foreign keys and link for many-to-many relationship

This commit is contained in:
linuskmr 2021-12-25 19:24:43 +01:00
parent 96573e7d48
commit 2255f9edcd
5 changed files with 33 additions and 29 deletions

View file

@ -0,0 +1,8 @@
from typing import Optional
from sqlmodel import SQLModel, Field
class RecordTagLink(SQLModel, table=True):
record_id: Optional[int] = Field(default=None, foreign_key="record.id", primary_key=True)
tag_id: Optional[int] = Field(default=None, foreign_key="tag.id", primary_key=True)

View file

@ -1,13 +1,14 @@
from datetime import datetime, timedelta from datetime import datetime, timedelta
from typing import Optional from typing import Optional
from sqlmodel import SQLModel, Field from sqlmodel import SQLModel, Field, Relationship
class ProjectBase(SQLModel): class ProjectBase(SQLModel):
"""Superclass model which all project classes have in common.""" """Superclass model which all project classes have in common."""
name: str # = Field(description="Name of the project", example="Learning") name: str
creation_date: datetime = Field(default=datetime.now())
class ProjectCreate(ProjectBase): class ProjectCreate(ProjectBase):
@ -19,21 +20,12 @@ class Project(ProjectBase, table=True):
"""Model used inside the database.""" """Model used inside the database."""
id: Optional[int] = Field(default=None, primary_key=True) id: Optional[int] = Field(default=None, primary_key=True)
creation_date: datetime = Field(default=datetime.now()) records: list["Record"] = Relationship(back_populates="project")
class ProjectRead(ProjectBase): class ProjectRead(ProjectBase):
"""Model used when querying information about a module.""" """Model used when querying information about a module."""
id: int id: int
creation_date: datetime # = Field(description="Project creation date", example=datetime.now()) creation_date: datetime
# duration: timedelta # = Field(description="Total tracked duration", example=timedelta(days=3, hours=5, records: list[int]
# minutes=47))
# records: int # = Field(description="Total number of trackings/records", example=42)
# class Config: # TODO: Adding this config may be done with a decorator
# """pydantic config"""
# json_encoders = {
# # Serialize timedeltas as ISO 8601 and not as float seconds, which is the default
# timedelta: timedelta_isoformat,
# }

View file

@ -1,30 +1,36 @@
from datetime import datetime from datetime import datetime
from typing import Optional from typing import Optional
from sqlmodel import SQLModel, Field from sqlmodel import SQLModel, Field, Relationship
from src.models.links import RecordTagLink
class RecordBase(SQLModel): class RecordBase(SQLModel):
"""Superclass model that all record classes have in common.""" """Superclass model that all record classes have in common."""
project: int = Field(foreign_key="project.id")
start: datetime = Field(default=datetime.now()) start: datetime = Field(default=datetime.now())
end: Optional[datetime] = Field(default=None) end: Optional[datetime] = Field(default=None)
tags: list[str]
class RecordCreate(RecordBase): class RecordCreate(RecordBase):
"""Model used when a user creates a record.""" """Model used when a user creates a record."""
pass
project: int
tags: list[int] = Field(default=list())
class Record(RecordBase, table=True): class Record(RecordBase, table=True):
"""Model used inside the database.""" """Model used inside the database."""
id: Optional[int] = Field(default=None, primary_key=True) id: Optional[int] = Field(default=None, primary_key=True)
project: Optional["Project"] = Relationship(back_populates="records")
tags: list["Tag"] = Relationship(back_populates="records", link_model=RecordTagLink)
class RecordRead(RecordBase): class RecordRead(RecordBase):
"""Model used when a user queries a record.""" """Model used when a user queries a record."""
pass id: int
project: int
tags: list[int]

View file

@ -1,13 +1,16 @@
from datetime import datetime, timedelta from datetime import datetime, timedelta
from typing import Optional from typing import Optional
from sqlmodel import SQLModel, Field from sqlmodel import SQLModel, Field, Relationship
from src.models.links import RecordTagLink
class TagBase(SQLModel): class TagBase(SQLModel):
"""Superclass model which all tag classes have in common.""" """Superclass model which all tag classes have in common."""
name: str # = Field(description="Name of the tag", example="Listening Lectures") name: str
records: list["Record"] = Relationship(back_populates="tags", link_model=RecordTagLink)
class TagCreate(TagBase): class TagCreate(TagBase):
@ -24,6 +27,4 @@ class TagRead(TagBase):
"""Model used when querying information about a tag.""" """Model used when querying information about a tag."""
id: int id: int
name: str # = Field(description="Name of the tag", example="Listening Lectures") name: str
# duration: timedelta # = Field(description="Total tracked duration", example=timedelta(days=3, hours=5,
# minutes=47))

View file

@ -1,6 +1,3 @@
import logging
from datetime import datetime, timedelta
from fastapi import APIRouter, status, Path, Depends, HTTPException from fastapi import APIRouter, status, Path, Depends, HTTPException
from sqlmodel import select, Session from sqlmodel import select, Session
@ -14,14 +11,14 @@ router = APIRouter(prefix="/records", tags=["Records"])
async def all_records( async def all_records(
*, *,
session: Session = Depends(database.get_session) session: Session = Depends(database.get_session)
) -> list[RecordRead]: ) -> list[Record]:
"""Returns a list of all records.""" """Returns a list of all records."""
records = session.exec(select(Record)).all() records = session.exec(select(Record)).all()
return records return records
@router.post("/start", status_code=status.HTTP_201_CREATED) @router.post("/", status_code=status.HTTP_201_CREATED)
async def add_record( async def add_record(
*, *,
record: RecordCreate, record: RecordCreate,