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 typing import Optional
from sqlmodel import SQLModel, Field
from sqlmodel import SQLModel, Field, Relationship
class ProjectBase(SQLModel):
"""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):
@ -19,21 +20,12 @@ class Project(ProjectBase, table=True):
"""Model used inside the database."""
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):
"""Model used when querying information about a module."""
id: int
creation_date: datetime # = Field(description="Project creation date", example=datetime.now())
# duration: timedelta # = Field(description="Total tracked duration", example=timedelta(days=3, hours=5,
# 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,
# }
creation_date: datetime
records: list[int]

View file

@ -1,30 +1,36 @@
from datetime import datetime
from typing import Optional
from sqlmodel import SQLModel, Field
from sqlmodel import SQLModel, Field, Relationship
from src.models.links import RecordTagLink
class RecordBase(SQLModel):
"""Superclass model that all record classes have in common."""
project: int = Field(foreign_key="project.id")
start: datetime = Field(default=datetime.now())
end: Optional[datetime] = Field(default=None)
tags: list[str]
class RecordCreate(RecordBase):
"""Model used when a user creates a record."""
pass
project: int
tags: list[int] = Field(default=list())
class Record(RecordBase, table=True):
"""Model used inside the database."""
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):
"""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 typing import Optional
from sqlmodel import SQLModel, Field
from sqlmodel import SQLModel, Field, Relationship
from src.models.links import RecordTagLink
class TagBase(SQLModel):
"""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):
@ -24,6 +27,4 @@ class TagRead(TagBase):
"""Model used when querying information about a tag."""
id: int
name: str # = Field(description="Name of the tag", example="Listening Lectures")
# duration: timedelta # = Field(description="Total tracked duration", example=timedelta(days=3, hours=5,
# minutes=47))
name: str

View file

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