Fix bugs, add README and Makefile

This commit is contained in:
2026-01-16 20:39:51 +03:00
parent 3e515c66ec
commit a065c6b7be
30 changed files with 695 additions and 286 deletions

View File

@@ -1,7 +1,8 @@
import contextvars
from contextlib import asynccontextmanager, contextmanager
from typing import Generic, TypeVar
from typing import AsyncGenerator, Generator, Generic, TypeVar
from pydantic_filters import BasePagination, BaseSort
from pydantic_filters.drivers.sqlalchemy import append_to_statement
from sqlalchemy import func
from sqlalchemy.exc import IntegrityError
@@ -9,7 +10,9 @@ from sqlalchemy.ext.asyncio import create_async_engine
from sqlmodel import delete, insert, select, update
from sqlmodel.ext.asyncio.session import AsyncSession
from birthday_pool_bot.interfaces import RepositoryInterface
from .exceptions import AlreadyExistsError, HaveNoSessionError
from .settings import RepositorySettings
from .tables import BaseSQLModel
DTOType = TypeVar("DTOType")

View File

@@ -12,7 +12,7 @@ from .migrator import Migrator
def callback(ctx: typer.Context):
ctx.obj = ctx.obj or {}
settings = ctx.obj["settings"]
settings: Settings = ctx.obj["settings"]
ctx.obj["migrator"] = Migrator(settings=settings.repository)

View File

@@ -27,7 +27,7 @@ def upgrade() -> None:
sa.Column("name", sqlmodel.sql.sqltypes.AutoString(), nullable=True),
sa.Column("birthday", sa.Date(), nullable=True),
sa.Column("phone", sqlmodel.sql.sqltypes.AutoString(), nullable=True),
sa.Column("telegram_id", sa.Integer(), nullable=True),
sa.Column("telegram_id", sa.BigInteger(), nullable=True),
sa.Column("gift_payment_data", sa.JSON(), nullable=True),
sa.PrimaryKeyConstraint("id"),
sa.UniqueConstraint("id"),

View File

@@ -1,4 +1,7 @@
from pydantic_filters import OffsetPagination
import uuid
from typing import AsyncGenerator
from pydantic_filters import BasePagination, OffsetPagination
from sqlalchemy.orm import joinedload
from birthday_pool_bot.dto import Pool, PoolFilter
@@ -14,20 +17,38 @@ class PoolsRepository(BaseRepository[Pool, PoolFilter]):
filter_ = PoolFilter(birthday_user_id={birthday_user_id})
return await self.get_items_count(filter_=filter_)
async def get_pools_by_birthday_user_id(self, birthday_user_id: uuid.UUID) -> list[Pool]:
async def get_pools_by_birthday_user_id(
self,
birthday_user_id: uuid.UUID,
pagination: BasePagination | None = None,
with_owner: bool = False,
) -> AsyncGenerator[Pool]:
filter_ = PoolFilter(birthday_user_id={birthday_user_id})
return [pool async for pool in self.get_items(filter_=filter_)]
options = []
if with_owner:
options.append(joinedload(DBPool.owner))
pools_generator = self.get_items(
filter_=filter_,
pagination=pagination,
options=options,
)
async for pool in pools_generator:
yield pool
async def get_pool_by_id(
self,
pool_id: uuid.UUID,
with_owner: bool = False,
with_birthday_user: bool = False,
) -> Pool | None:
filter_ = PoolFilter(id={pool_id})
pagination = OffsetPagination(limit=1)
options = []
if with_owner:
options.append(joinedload(DBPool.owner))
if with_birthday_user:
options.append(joinedload(DBPool.birthday_user))
pools_generator = self.get_items(
filter_=filter_,

View File

@@ -1,4 +1,5 @@
import uuid
from typing import AsyncGenerator, Iterable
from pydantic_filters import BasePagination, OffsetPagination
from sqlalchemy.orm import joinedload

View File

@@ -1,8 +1,9 @@
import uuid
from datetime import date
from typing import Container, Sequence, TypeVar
from pydantic_filters import OffsetPagination
from sqlalchemy import Column, func, inspect, select
from pydantic_filters import BasePagination, OffsetPagination
from sqlalchemy import Column, func, inspect, or_, select, update
from sqlmodel import SQLModel
from birthday_pool_bot.dto import User, UserFilter

View File

@@ -1,13 +1,12 @@
import uuid
import enum
from datetime import date
from typing import Self, List
from typing import Any, Self
import sqlalchemy as sa
from pydantic import BaseModel
from sqlmodel import SQLModel, Field, Relationship
from birthday_pool_bot.dto import (
BankEnum,
PaymentData as DTOPaymentData,
Pool as DTOPool,
Subscription as DTOSubscription,
@@ -46,7 +45,10 @@ class User(BaseSQLModel, table=True):
name: str | None = Field(nullable=True)
birthday: date | None = Field(nullable=True)
phone: str | None = Field(default=None, nullable=True)
telegram_id: int | None = Field(default=None, nullable=True)
telegram_id: int | None = Field(
default=None,
sa_column=sa.Column(sa.BigInteger(), nullable=True),
)
gift_payment_data: dict | None = Field(
sa_column=sa.Column(sa.JSON, nullable=True),
default_factory=dict,
@@ -118,6 +120,12 @@ class Pool(BaseSQLModel, table=True):
"lazy": None,
},
)
birthday_user: User = Relationship(
sa_relationship_kwargs={
"primaryjoin": "User.id == Pool.birthday_user_id",
"lazy": None,
},
)
@classmethod
def from_item(cls, item: DTOPool) -> Self:
@@ -128,6 +136,11 @@ class Pool(BaseSQLModel, table=True):
description=item.description,
payment_data=item.payment_data.model_dump_json(),
owner=None if item.owner is None else DTOUser.from_item(item.owner),
birthday_user=(
None
if item.birthday_user is None else
DTOUser.from_item(item.birthday_user)
),
)
def to_item(self) -> DTOPool:
@@ -137,7 +150,8 @@ class Pool(BaseSQLModel, table=True):
birthday_user_id=self.birthday_user_id,
description=self.description,
payment_data=DTOPaymentData.model_validate_json(self.payment_data),
owner=None if self.owner is None else self.owner.to_item()
owner=None if self.owner is None else self.owner.to_item(),
birthday_user=None if self.birthday_user is None else self.birthday_user.to_item(),
)