diff --git a/alembic.ini b/alembic.ini index 44c9a46..4f70ed2 100644 --- a/alembic.ini +++ b/alembic.ini @@ -60,7 +60,7 @@ version_path_separator = os # Use os.pathsep. Default configuration used for ne # are written from script.py.mako # output_encoding = utf-8 -sqlalchemy.url = postgresql://demo_user:user_pass@localhost:5432/serviceman_db +sqlalchemy.url = postgresql://demo_user:user_pass@db:5432/serviceman_db [post_write_hooks] diff --git a/api/migrations/versions/629b2e73e311_initial.py b/api/migrations/versions/629b2e73e311_initial.py new file mode 100644 index 0000000..9638a71 --- /dev/null +++ b/api/migrations/versions/629b2e73e311_initial.py @@ -0,0 +1,23 @@ +"""initial + +Revision ID: 629b2e73e311 +Revises: +Create Date: 2024-03-12 00:58:28.851188 + +""" + +from collections.abc import Sequence + +# revision identifiers, used by Alembic. +revision: str = "629b2e73e311" +down_revision: str | None = None +branch_labels: str | Sequence[str] | None = None +depends_on: str | Sequence[str] | None = None + + +def upgrade() -> None: + pass + + +def downgrade() -> None: + pass diff --git a/api/migrations/versions/3ba730985688_initial.py b/api/migrations/versions/e98840064cab_first.py similarity index 51% rename from api/migrations/versions/3ba730985688_initial.py rename to api/migrations/versions/e98840064cab_first.py index 89b0e73..d0c55e5 100644 --- a/api/migrations/versions/3ba730985688_initial.py +++ b/api/migrations/versions/e98840064cab_first.py @@ -1,8 +1,8 @@ -"""initial +"""First -Revision ID: 3ba730985688 -Revises: -Create Date: 2024-03-06 03:10:09.050166 +Revision ID: e98840064cab +Revises: 629b2e73e311 +Create Date: 2024-03-12 01:00:58.640179 """ @@ -12,8 +12,8 @@ import sqlalchemy as sa from alembic import op # revision identifiers, used by Alembic. -revision: str = "3ba730985688" -down_revision: str | None = None +revision: str = "e98840064cab" +down_revision: str | None = "629b2e73e311" branch_labels: str | Sequence[str] | None = None depends_on: str | Sequence[str] | None = None @@ -22,13 +22,17 @@ def upgrade() -> None: # ### commands auto generated by Alembic - please adjust! ### op.create_table( "users", - sa.Column("email", sa.String(), nullable=True), - sa.Column("hashed_password", sa.String(), nullable=True), - sa.Column("is_active", sa.Boolean(), nullable=True), - sa.Column("name", sa.String(), nullable=False), + sa.Column("first_name", sa.String(), nullable=False), + sa.Column("mid_name", sa.String(), nullable=False), + sa.Column("last_name", sa.String(), nullable=False), + sa.Column("email", sa.String(), nullable=False), + sa.Column("telegram_id", sa.String(), nullable=False), + sa.Column("hashed_password", sa.String(), nullable=False), + sa.Column("is_active", sa.Boolean(), nullable=False), sa.Column("id", sa.UUID(), nullable=False), sa.PrimaryKeyConstraint("id"), sa.UniqueConstraint("email"), + sa.UniqueConstraint("telegram_id"), ) # ### end Alembic commands ### diff --git a/api/models/user_model.py b/api/models/user_model.py index e6960bd..6830a25 100644 --- a/api/models/user_model.py +++ b/api/models/user_model.py @@ -1,7 +1,4 @@ -from sqlalchemy import Boolean, Column, String -from sqlalchemy.orm import Mapped - -from api.schemas import UserReadDTO +from sqlalchemy.orm import Mapped, mapped_column from . import Base @@ -9,10 +6,15 @@ from . import Base class UserModel(Base): __tablename__ = "users" - name: Mapped[str] - email = Column(String, unique=True) - hashed_password = Column(String) - is_active = Column(Boolean, default=True) + first_name: Mapped[str] + mid_name: Mapped[str] + last_name: Mapped[str] + + email: Mapped[str] = mapped_column(unique=True) + telegram_id: Mapped[str] = mapped_column(unique=True) + + hashed_password: Mapped[str] + is_active: Mapped[bool] = mapped_column(default=False) def __repr__(self): return ( @@ -21,9 +23,3 @@ class UserModel(Base): f'hashed_password="{self.hashed_password}", ' f"is_active={self.is_active})>" ) - - def to_read_model(self) -> UserReadDTO: - return UserReadDTO( - id=self.id, - name=self.name, - ) diff --git a/api/repositories/__init__.py b/api/repositories/__init__.py index bf53d8f..a447006 100644 --- a/api/repositories/__init__.py +++ b/api/repositories/__init__.py @@ -1,7 +1,3 @@ -from .repository import AbstractRepository from .user import UserRepository -__all__ = ( - "AbstractRepository", - "UserRepository", -) +__all__ = ("UserRepository",) diff --git a/api/repositories/repository.py b/api/repositories/repository.py deleted file mode 100644 index ff7060e..0000000 --- a/api/repositories/repository.py +++ /dev/null @@ -1,23 +0,0 @@ -from abc import ABC, abstractmethod - - -class AbstractRepository(ABC): - @abstractmethod - async def add_one(self, data: dict): - raise NotImplementedError() - - @abstractmethod - async def find_all(self): - raise NotImplementedError() - - @abstractmethod - async def find_one(self, filter: dict): - raise NotImplementedError() - - @abstractmethod - async def update_one(self, filter: dict, data: dict): - raise NotImplementedError() - - @abstractmethod - async def delete_one(self, filter: dict): - raise NotImplementedError() diff --git a/api/repositories/user.py b/api/repositories/user.py index bb0d618..0ea87fd 100644 --- a/api/repositories/user.py +++ b/api/repositories/user.py @@ -2,22 +2,25 @@ from sqlalchemy import insert, select from sqlalchemy.ext.asyncio.session import AsyncSession from api.models import UserModel -from api.repositories import AbstractRepository +from api.schemas.user_schema import UserReadDTO, UserWriteDTO -class UserRepository(AbstractRepository): +class UserRepository: def __init__(self, session: AsyncSession): self.session = session - async def add_one(self, data: dict): - stmt = insert(UserModel).values(**data) + async def add_one( + self, + data: UserWriteDTO, + ): + stmt = insert(UserModel).values(**data.model_dump()) res = await self.session.execute(stmt) - return res.scalar_one() + return UserReadDTO.model_validate(res.scalar_one()) async def find_all(self): stmt = select(UserModel) res = await self.session.execute(stmt) - res = [row[0].to_read_model() for row in res.all()] + res = [UserReadDTO.model_validate(row) for row in res.scalars().all()] return res async def find_one(self, filter: dict): diff --git a/api/schemas/__init__.py b/api/schemas/__init__.py index 678507a..4b99d40 100644 --- a/api/schemas/__init__.py +++ b/api/schemas/__init__.py @@ -1,7 +1,8 @@ -from .base_schema import ReadDTO, WriteDTO +from .base_schema import BaseDTO, ReadDTO, WriteDTO from .user_schema import UserReadDTO, UserWriteDTO __all__ = ( + "BaseDTO", "WriteDTO", "ReadDTO", "UserWriteDTO", diff --git a/api/schemas/base_schema.py b/api/schemas/base_schema.py index 6faffa3..bec3169 100644 --- a/api/schemas/base_schema.py +++ b/api/schemas/base_schema.py @@ -3,11 +3,14 @@ from uuid import UUID from pydantic import BaseModel -class WriteDTO(BaseModel): - +class BaseDTO(BaseModel): class Config: from_attributes = True +class WriteDTO(BaseDTO): + pass + + class ReadDTO(WriteDTO): id: UUID diff --git a/api/uow/uow_base.py b/api/uow/uow_base.py index 1f46aca..a7bdd63 100644 --- a/api/uow/uow_base.py +++ b/api/uow/uow_base.py @@ -7,10 +7,7 @@ class UnitOfWork: async def __aenter__(self): self.session = self.session_factory() - self.users = UserRepository(self.session) - print("session id:", id(self.session)) - print("UoW obj id:", id(self)) async def __aexit__(self, *args): await self.session.rollback()