Add foreign keys and link for many-to-many relationship
This commit is contained in:
parent
96573e7d48
commit
2255f9edcd
5 changed files with 33 additions and 29 deletions
8
backend/src/models/links.py
Normal file
8
backend/src/models/links.py
Normal 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)
|
|
@ -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]
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in a new issue