FASTAPI SQLAlchemy PSQL How to Post data with relationships

42 views Asked by At
migrations
src
src/__pycache__
src/auth
src/auth/__pycache__
src/auth/base_config.py
src/auth/manager.py > incapsulated funcs like create
src/auth/models.py > user
src/auth/schemas.py > pydantic classes for handling requests
src/auth/utils.py
src/place
src/place/__pycache__
src/place/manager.py > incapsulated funcs like create
src/place/models.py > place, placeimage, review
src/place/schemas.py > pydantic classes for handling requests
src/__init__.py
src/config.py
src/database.py > db conn
src/main.py > routes
.env
.env.example
.gitignore
alembic.ini
README.md
requirements.txt

Hello! First I show my code and ask then.

src/auth/models

metadata = MetaData()
Base: DeclarativeMeta = declarative_base(metadata=metadata)

class User(SQLAlchemyBaseUserTable[int], Base):
    __tablename__ = "user"

    id = Column(Integer, primary_key=True)
    email: str = Column(String(length=320), unique=True, index=True, nullable=True)
    username = Column(String, nullable=False)
    hashed_password: str = Column(String(length=1024), nullable=True)
    registered_at = Column(TIMESTAMP, nullable=False, default=datetime.utcnow())
    is_active: bool = Column(Boolean, default=True, nullable=False)
    is_superuser: bool = Column(Boolean, default=False, nullable=False)
    is_verified: bool = Column(Boolean, default=False, nullable=False)

src/place/models

metadata = MetaData()
Base: DeclarativeMeta = declarative_base(metadata=metadata)

def _resolve_user_model():
    from auth.models import User

    return User

class Test(Base):
    __tablename__ = "test"

    id = Column(Integer, primary_key=True)
    title: str = Column(String(length=320), unique=True, nullable=False)
    about: str = Column(String(length=320), nullable=False)

class Place(Base):
    __tablename__ = "place"

    id = Column(Integer, primary_key=True)
    title: str = Column(String(length=320), unique=True, nullable=False)
    latitude: float = Column(Float, nullable=False)
    longitude: float = Column(Float, nullable=False)
    user_id = Column(Integer, ForeignKey(_resolve_user_model().id), nullable=False)
    reviews = relationship("Review", back_populates="place")
    images = relationship("PlaceImage", back_populates="place")


class PlaceImage(Base):
    __tablename__ = "place_image"

    id = Column(Integer, primary_key=True)
    photo_name = Column(String, nullable=False)
    photo_url = Column(String, nullable=False)
    is_verified_photo: bool = Column(Boolean, default=False, nullable=False)
    place_id = Column(Integer, ForeignKey("place.id"), nullable=False)
    place = relationship("Place", back_populates="images")

class Review(Base):
    __tablename__ = "review"

    id = Column(Integer, primary_key=True)
    text = Column(String, nullable=False)
    place_id = Column(Integer, ForeignKey("place.id"), nullable=False)
    place = relationship("Place", back_populates="reviews")
    user_id = Column(Integer, ForeignKey(_resolve_user_model().id), nullable=False)
    user = relationship(_resolve_user_model())

Problem is 1. Can't create POST request in @app.post(/create-place) to create place which will contain list of place images AND user (creator) ID (I use FASTAPI_USERS lib).

class PlaceImageCreate(BaseModel):
    photo_name: str
    photo_url: str


class PlaceCreate(BaseModel):
    title: str
    latitude: float
    longitude: float
    user_id: int
    images: List[PlaceImageCreate]

class TestCreate(BaseModel):
    title: str
    about: str
from sqlalchemy.ext.asyncio import AsyncSession
from src.place.models import Place, PlaceImage, Test
from src.place.schemas import PlaceCreate, TestCreate
from fastapi import Depends
from auth.models import User
from auth.base_config import current_user

async def create_place(db: AsyncSession, place: PlaceCreate, current_user: User = Depends(current_user)) -> Place:
    db_place = Place(
        title=place.title,
        latitude=place.latitude,
        longitude=place.longitude,
        user_id=place.user_id
    )
    db.add(db_place)
    await db.commit()
    await db.refresh(db_place)
    return db_place

I tried this block of code and it works ofc

async def _create_test(db: AsyncSession, test: TestCreate) -> Test:
    db_test = Test(
        title=test.title,
        about=test.about
    )
    db.add(db_test)
    await db.commit()
    await db.refresh(db_test)
    return db_test

but I dont understand how to make places with images, userid and reviews...

0

There are 0 answers