pysql-repo


Namepysql-repo JSON
Version 0.7.4.0 PyPI version JSON
download
home_pagehttps://github.com/Impro02/pysql-repo
SummaryA project to have a base repository class to perform select/insert/update/delete with dynamic syntax
upload_time2024-07-16 09:39:00
maintainerNone
docs_urlNone
authorMaxime MARTIN
requires_python>=3.8
licenseMIT
keywords
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            The pysql-repo library is a Python library that is designed to use the session/repository pattern to interact with databases in Python projects. It provides a more flexible notation for running SQL queries and is built on top of SQLAlchemy, a popular Python SQL toolkit. With pysql_repo, users can write SQL queries using a new, more intuitive syntax, simplifying the process of working with SQL databases in Python and making it easier to write and maintain complex queries.

## Installing pysql-repo

To install pysql-repo, if you already have Python, you can install with:

```
pip install pysql_repo
```

## How to import pysql-repo

To access pysql-repo and its functions import it in your Python code like this:

```
from pysql_repo import Database, Repository, Service, with_session, Operators, LoadingTechnique, RelationshipOption
```

To access pysql-repo and its asyncio functions import it in your Python code like this:

```
from pysql_repo.asyncio import AsyncDatabase, AsyncRepository, AsyncService, with_async_session
```

## Reading the example code

```
# MODULES
from typing import List

# SQLALCHEMY
from sqlalchemy import Boolean, ForeignKey, Integer, String
from sqlalchemy.orm import relationship, Mapped, mapped_column
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()


class City(Base):
    __tablename__ = "CITY"

    id: Mapped[int] = mapped_column(
        "ID",
        Integer,
        primary_key=True,
        index=True,
    )
    name: Mapped[str] = mapped_column(
        "NAME",
        String,
        index=True,
    )
    state: Mapped[str] = mapped_column(
        "STATE",
        String,
        index=True,
    )

    addresses: Mapped[List["Address"]] = relationship(
        "Address",
        back_populates="city",
        lazy="joined",
        cascade="all, delete-orphan",
    )


class Address(Base):
    __tablename__ = "ADDRESS"

    id: Mapped[int] = mapped_column(
        "ID",
        Integer,
        primary_key=True,
        index=True,
    )
    street: Mapped[str] = mapped_column(
        "STREET",
        String,
        index=True,
    )
    zip_code: Mapped[str] = mapped_column(
        "ZIP_CODE",
        Integer,
        index=True,
    )
    user_id: Mapped[int] = mapped_column(
        "USER_ID",
        Integer,
        ForeignKey("USER.ID"),
    )
    city_id: Mapped[int] = mapped_column(
        "CITY_ID",
        Integer,
        ForeignKey("CITY.ID"),
    )

    user: Mapped["User"] = relationship(
        "User",
        back_populates="addresses",
        lazy="joined",
    )
    city: Mapped["City"] = relationship(
        "City",
        back_populates="addresses",
        lazy="joined",
    )


class User(Base):
    __tablename__ = "USER"

    id: Mapped[int] = mapped_column(
        "ID",
        Integer,
        primary_key=True,
        index=True,
    )
    email: Mapped[str] = mapped_column(
        "EMAIL",
        String,
        unique=True,
        index=True,
    )
    hashed_password: Mapped[str] = mapped_column(
        "HASHED_PASSWORD",
        String,
    )
    full_name: Mapped[str] = mapped_column(
        "FULL_NAME",
        String,
        index=True,
    )
    is_active: Mapped[bool] = mapped_column(
        "IS_ACTIVE",
        Boolean,
        default=True,
    )

    addresses: Mapped[List["Address"]] = relationship(
        "Address",
        back_populates="user",
        lazy="joined",
        cascade="all, delete-orphan",
    )
```

To create an instance of Database and generate an instance of Session from the factory:

```
import logging

logging.basicConfig()
logger_db = logging.get_logger('demo')

database = DataBase(
    databases_config={
        "connection_string": "foo",
    },
    base=Base,
    logger=logger_db,
)

database.create_database()

with database.session_factory() as session:
    session.execute(...)
```

To create a repository, you just have to inherit your class from Repository.

```
# MODULES
from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple

# SQLALCHEMY
from sqlalchemy.orm import Column, Session

# PYSQL_REPO
from pysql_repo import Operators, Repository, LoadingTechnique, RelationshipOption

# CONTEXTLIB
from contextlib import AbstractContextManager

# MODEL
from tests.repositories.user._base import UserRepositoryBase as _UserRepositoryBase
from tests.models.database.database import Address, User
from tests.models.schemas.user import UserCreate


class UserRepositoryBase:
    @classmethod
    def get_filters(
        cls,
        ids_in: Optional[List[int]] = None,
        ids_not_in: Optional[List[int]] = None,
        emails_iin: Optional[List[str]] = None,
        emails_in: Optional[List[str]] = None,
        emails_not_iin: Optional[List[str]] = None,
        emails_not_in: Optional[List[str]] = None,
        email_ilike: Optional[List[str]] = None,
        email_like: Optional[List[str]] = None,
        email_not_ilike: Optional[List[str]] = None,
        email_not_like: Optional[List[str]] = None,
        email_equal: Optional[str] = None,
        email_iequal: Optional[str] = None,
        email_different: Optional[str] = None,
        email_idifferent: Optional[str] = None,
        zip_codes_in: Optional[List[str]] = None,
        zip_codes_not_in: Optional[List[str]] = None,
        is_active_equal: Optional[bool] = None,
    ) -> Dict[Column, Any]:
        return {
            User.id: {
                Operators.IN: ids_in,
                Operators.NOT_IN: ids_not_in,
            },
            User.email: {
                Operators.IIN: emails_iin,
                Operators.IN: emails_in,
                Operators.NOT_IIN: emails_not_iin,
                Operators.NOT_IN: emails_not_in,
                Operators.ILIKE: email_ilike,
                Operators.LIKE: email_like,
                Operators.NOT_ILIKE: email_not_ilike,
                Operators.NOT_LIKE: email_not_like,
                Operators.EQUAL: email_equal,
                Operators.IEQUAL: email_iequal,
                Operators.DIFFERENT: email_different,
                Operators.IDIFFERENT: email_idifferent,
            },
            User.is_active: {
                Operators.EQUAL: is_active_equal,
            },
            User.addresses: {
                Operators.ANY: {
                    Address.zip_code: {
                        Operators.IN: zip_codes_in,
                        Operators.NOT_IN: zip_codes_not_in,
                    },
                }
            },
        }

    @classmethod
    def get_relationship_options(
        cls,
        load_addresses: bool = False,
        load_city: bool = False,
        zip_codes_not_in: Optional[List[int]] = None,
        zip_codes_in: Optional[List[int]] = None,
    ):
        extra_join_addresses = []
        if zip_codes_not_in:
            extra_join_addresses.append(Address.zip_code.not_in(zip_codes_not_in))
        if zip_codes_in:
            extra_join_addresses.append(Address.zip_code.in_(zip_codes_in))

        return {
            User.addresses: RelationshipOption(
                lazy=LoadingTechnique.JOINED
                if load_addresses
                else LoadingTechnique.NOLOAD,
                added_criteria=extra_join_addresses
                if len(extra_join_addresses) > 0
                else None,
                children={
                    Address.city: RelationshipOption(
                        lazy=LoadingTechnique.JOINED
                        if load_city
                        else LoadingTechnique.NOLOAD,
                    )
                },
            ),
        }


class UserRepository(Repository, _UserRepositoryBase):
    def __init__(
        self,
        session_factory: Callable[..., AbstractContextManager[Session]],
    ) -> None:
        super().__init__(session_factory)

    def get_all(
        self,
        __session__: Session,
        /,
        ids_in: Optional[List[int]] = None,
        ids_not_in: Optional[List[int]] = None,
        emails_iin: Optional[List[str]] = None,
        emails_in: Optional[List[str]] = None,
        emails_not_iin: Optional[List[str]] = None,
        emails_not_in: Optional[List[str]] = None,
        email_ilike: Optional[str] = None,
        email_like: Optional[str] = None,
        email_not_ilike: Optional[str] = None,
        email_not_like: Optional[str] = None,
        email_equal: Optional[str] = None,
        email_iequal: Optional[str] = None,
        email_different: Optional[str] = None,
        email_idifferent: Optional[str] = None,
        zip_codes_in: Optional[List[int]] = None,
        zip_codes_not_in: Optional[List[int]] = None,
        is_active_equal: Optional[bool] = None,
        load_addresses: bool = True,
        load_city: bool = True,
        order_by: Optional[List[str]] = None,
        direction: Optional[List[str]] = None,
    ) -> Sequence[User]:
        users = self._select_all(
            __session__,
            model=User,
            optional_filters=self.get_filters(
                ids_in=ids_in,
                ids_not_in=ids_not_in,
                emails_iin=emails_iin,
                emails_in=emails_in,
                emails_not_iin=emails_not_iin,
                emails_not_in=emails_not_in,
                email_ilike=email_ilike,
                email_like=email_like,
                email_not_ilike=email_not_ilike,
                email_not_like=email_not_like,
                email_equal=email_equal,
                email_iequal=email_iequal,
                email_different=email_different,
                email_idifferent=email_idifferent,
                zip_codes_in=zip_codes_in,
                zip_codes_not_in=zip_codes_not_in,
                is_active_equal=is_active_equal,
            ),
            relationship_options=self.get_relationship_options(
                load_addresses=load_addresses,
                load_city=load_city,
                zip_codes_in=zip_codes_in,
                zip_codes_not_in=zip_codes_not_in,
            ),
            order_by=order_by,
            direction=direction,
        )

        return users

    def get_paginate(
        self,
        __session__: Session,
        /,
        page: int,
        per_page: int,
        ids_in: Optional[List[int]] = None,
        ids_not_in: Optional[List[int]] = None,
        emails_iin: Optional[List[str]] = None,
        emails_in: Optional[List[str]] = None,
        emails_not_iin: Optional[List[str]] = None,
        emails_not_in: Optional[List[str]] = None,
        email_ilike: Optional[str] = None,
        email_like: Optional[str] = None,
        email_not_ilike: Optional[str] = None,
        email_not_like: Optional[str] = None,
        email_equal: Optional[str] = None,
        email_iequal: Optional[str] = None,
        email_different: Optional[str] = None,
        email_idifferent: Optional[str] = None,
        zip_codes_in: Optional[List[int]] = None,
        zip_codes_not_in: Optional[List[int]] = None,
        is_active_equal: Optional[bool] = None,
        load_addresses: bool = True,
        load_city: bool = True,
        order_by: Optional[List[str]] = None,
        direction: Optional[List[str]] = None,
    ) -> Tuple[Sequence[User], str]:
        users, pagination = self._select_paginate(
            __session__,
            model=User,
            optional_filters=self.get_filters(
                ids_in=ids_in,
                ids_not_in=ids_not_in,
                emails_iin=emails_iin,
                emails_in=emails_in,
                emails_not_iin=emails_not_iin,
                emails_not_in=emails_not_in,
                email_ilike=email_ilike,
                email_like=email_like,
                email_not_ilike=email_not_ilike,
                email_not_like=email_not_like,
                email_equal=email_equal,
                email_iequal=email_iequal,
                email_different=email_different,
                email_idifferent=email_idifferent,
                zip_codes_in=zip_codes_in,
                zip_codes_not_in=zip_codes_not_in,
                is_active_equal=is_active_equal,
            ),
            relationship_options=self.get_relationship_options(
                load_addresses=load_addresses,
                load_city=load_city,
                zip_codes_in=zip_codes_in,
                zip_codes_not_in=zip_codes_not_in,
            ),
            order_by=order_by,
            direction=direction,
            page=page,
            per_page=per_page,
        )

        return users, pagination

    def get_by_id(
        self,
        __session__: Session,
        id: int,
    ) -> Optional[User]:
        user = self._select(
            __session__,
            model=User,
            filters={
                User.id: {
                    Operators.EQUAL: id,
                },
            },
        )

        return user

    def create(
        self,
        __session__: Session,
        /,
        data: UserCreate,
        flush: bool = False,
        commit: bool = True,
    ) -> User:
        user = self._add(
            __session__,
            model=User,
            values={
                User.email.key: data.email,
                User.hashed_password.key: data.hashed_password,
                User.full_name.key: data.full_name,
            },
            flush=flush,
            commit=commit,
        )

        return user

    def create_all(
        self,
        __session__: Session,
        /,
        data: List[UserCreate],
        flush: bool = False,
        commit: bool = True,
    ) -> Sequence[User]:
        users = self._add_all(
            __session__,
            model=User,
            values=[
                {
                    User.email.key: item.email,
                    User.hashed_password.key: item.hashed_password,
                    User.full_name.key: item.full_name,
                }
                for item in data
            ],
            flush=flush,
            commit=commit,
        )

        return users

    def patch_email(
        self,
        __session__: Session,
        /,
        id: int,
        email: str,
        flush: bool = False,
        commit: bool = True,
    ) -> Optional[User]:
        user = self._update(
            __session__,
            model=User,
            values={
                User.email.key: email,
            },
            filters={
                User.id: {
                    Operators.EQUAL: id,
                },
            },
            flush=flush,
            commit=commit,
        )

        return user

    def bulk_patch_email(
        self,
        __session__: Session,
        /,
        data: List[Tuple[int, str]],
        flush: bool = False,
        commit: bool = True,
    ) -> Sequence[User]:
        self._bulk_update(
            __session__,
            model=User,
            values=[
                {
                    User.id.key: id,
                    User.email.key: email,
                }
                for id, email in data
            ],
            flush=flush,
            commit=commit,
        )

        return self._select_all(
            __session__,
            model=User,
            filters={
                User.id: {
                    Operators.IN: [id for id, _ in data],
                },
            },
        )

    def patch_disable(
        self,
        __session__: Session,
        /,
        ids: List[int],
        flush: bool = False,
        commit: bool = True,
    ) -> Sequence[User]:
        users = self._update_all(
            __session__,
            model=User,
            values={
                User.is_active.key: False,
            },
            filters={
                User.id: {
                    Operators.IN: ids,
                },
            },
            flush=flush,
            commit=commit,
        )

        return users

    def delete(
        self,
        __session__: Session,
        /,
        id: int,
        flush: bool = False,
        commit: bool = True,
    ) -> bool:
        is_deleted = self._delete(
            __session__,
            model=User,
            filters={
                User.id: {
                    Operators.EQUAL: id,
                },
            },
            flush=flush,
            commit=commit,
        )

        return is_deleted

    def delete_all(
        self,
        __session__: Session,
        /,
        ids: List[int],
        flush: bool = False,
        commit: bool = True,
    ) -> bool:
        is_deleted = self._delete_all(
            __session__,
            model=User,
            filters={
                User.id: {
                    Operators.IN: ids,
                },
            },
            flush=flush,
            commit=commit,
        )

        return is_deleted
```

To create a service, you just have to inherit your class from Service.

```
# MODULES
from logging import Logger
from typing import List, Optional, Tuple

# SQLALCHEMY
from sqlalchemy.orm import Session

# PYSQL_REPO
from pysql_repo import Service, with_session

# REPOSITORIES
from tests.repositories.user.user_repository import UserRepository

# MODELS
from tests.models.schemas.user import UserCreate, UserRead


class UserService(Service[UserRepository]):
    def __init__(
        self,
        user_repository: UserRepository,
        logger: Logger,
    ) -> None:
        super().__init__(
            repository=user_repository,
        )
        self._logger = logger

    def get_users(
        self,
        __session__: Session,
        /,
        ids_in: Optional[List[int]] = None,
        ids_not_in: Optional[List[int]] = None,
        emails_iin: Optional[List[str]] = None,
        emails_in: Optional[List[str]] = None,
        emails_not_iin: Optional[List[str]] = None,
        emails_not_in: Optional[List[str]] = None,
        email_ilike: Optional[str] = None,
        email_like: Optional[str] = None,
        email_not_ilike: Optional[str] = None,
        email_not_like: Optional[str] = None,
        email_equal: Optional[str] = None,
        email_iequal: Optional[str] = None,
        email_different: Optional[str] = None,
        email_idifferent: Optional[str] = None,
        zip_codes_in: Optional[List[int]] = None,
        zip_codes_not_in: Optional[List[int]] = None,
        is_active_equal: Optional[bool] = None,
        load_addresses: bool = True,
        load_city: bool = True,
        order_by: Optional[List[str]] = None,
        direction: Optional[List[str]] = None,
    ) -> List[UserRead]:
        users = self._repository.get_all(
            __session__,
            ids_in=ids_in,
            ids_not_in=ids_not_in,
            emails_iin=emails_iin,
            emails_in=emails_in,
            emails_not_iin=emails_not_iin,
            emails_not_in=emails_not_in,
            email_ilike=email_ilike,
            email_like=email_like,
            email_not_ilike=email_not_ilike,
            email_not_like=email_not_like,
            email_equal=email_equal,
            email_iequal=email_iequal,
            email_different=email_different,
            email_idifferent=email_idifferent,
            zip_codes_in=zip_codes_in,
            zip_codes_not_in=zip_codes_not_in,
            is_active_equal=is_active_equal,
            load_addresses=load_addresses,
            load_city=load_city,
            order_by=order_by,
            direction=direction,
        )

        return [UserRead.model_validate(item) for item in users]

    def get_users_paginate(
        self,
        __session__: Session,
        /,
        page: int,
        per_page: int,
        ids_in: Optional[List[int]] = None,
        ids_not_in: Optional[List[int]] = None,
        emails_iin: Optional[List[str]] = None,
        emails_in: Optional[List[str]] = None,
        emails_not_iin: Optional[List[str]] = None,
        emails_not_in: Optional[List[str]] = None,
        email_ilike: Optional[str] = None,
        email_like: Optional[str] = None,
        email_not_ilike: Optional[str] = None,
        email_not_like: Optional[str] = None,
        email_equal: Optional[str] = None,
        email_iequal: Optional[str] = None,
        email_different: Optional[str] = None,
        email_idifferent: Optional[str] = None,
        zip_codes_in: Optional[List[int]] = None,
        zip_codes_not_in: Optional[List[int]] = None,
        is_active_equal: Optional[bool] = None,
        load_addresses: bool = True,
        load_city: bool = True,
        order_by: Optional[List[str]] = None,
        direction: Optional[List[str]] = None,
    ) -> Tuple[List[UserRead], str]:
        users, pagination = self._repository.get_paginate(
            __session__,
            page=page,
            per_page=per_page,
            ids_in=ids_in,
            ids_not_in=ids_not_in,
            emails_iin=emails_iin,
            emails_in=emails_in,
            emails_not_iin=emails_not_iin,
            emails_not_in=emails_not_in,
            email_ilike=email_ilike,
            email_like=email_like,
            email_not_ilike=email_not_ilike,
            email_not_like=email_not_like,
            email_equal=email_equal,
            email_iequal=email_iequal,
            email_different=email_different,
            email_idifferent=email_idifferent,
            zip_codes_in=zip_codes_in,
            zip_codes_not_in=zip_codes_not_in,
            is_active_equal=is_active_equal,
            load_addresses=load_addresses,
            load_city=load_city,
            order_by=order_by,
            direction=direction,
        )

        return [UserRead.model_validate(item) for item in users], pagination

    def get_user_by_id(
        self,
        __session__: Session,
        /,
        id: int,
    ) -> Optional[UserRead]:
        user = self._repository.get_by_id(
            __session__,
            id=id,
        )

        if user is None:
            return None

        return UserRead.model_validate(user)

    def create_user(
        self,
        __session__: Session,
        /,
        data: UserCreate,
    ) -> UserRead:
        user = self._repository.create(
            __session__,
            data=data,
            flush=True,
        )

        return UserRead.model_validate(user)

    def create_users(
        self,
        __session__: Session,
        /,
        data: List[UserCreate],
    ) -> List[UserRead]:
        users = self._repository.create_all(
            __session__,
            data=data,
            flush=True,
        )

        return [UserRead.model_validate(user) for user in users]

    def patch_email(
        self,
        __session__: Session,
        /,
        id: int,
        email: str,
    ) -> UserRead:
        user = self._repository.patch_email(
            __session__,
            id=id,
            email=email,
            flush=True,
        )

        return UserRead.model_validate(user)

    def bulk_patch_email(
        self,
        __session__: Session,
        /,
        data: List[Tuple[int, str]],
    ) -> List[UserRead]:
        users = self._repository.bulk_patch_email(
            __session__,
            data=data,
            flush=True,
        )

        return [UserRead.model_validate(user) for user in users]

    def patch_disable(
        self,
        __session__: Session,
        /,
        ids: List[int],
    ) -> List[UserRead]:
        users = self._repository.patch_disable(
            __session__,
            ids=ids,
            flush=True,
        )

        return [UserRead.model_validate(user) for user in users]

    def delete_by_id(
        self,
        __session__: Session,
        /,
        id: int,
    ) -> bool:
        return self._repository.delete(
            __session__,
            id=id,
            flush=True,
        )

    def delete_by_ids(
        self,
        __session__: Session,
        /,
        ids: List[int],
    ) -> bool:
        return self._repository.delete_all(
            __session__,
            ids=ids,
            flush=True,
        )
```

To create an instance of AsyncDatabase and generate an instance of AsyncSession from the factory:

```
import logging

logging.basicConfig()
logger_db = logging.get_logger('demo')

database = AsyncDataBase(
    databases_config={
        "connection_string": "foo",
    },
    base=Base,
    logger=logger_db,
)

await database.create_database()

async with database.session_factory() as session:
    await session.execute(...)
```

To create an async repository, you just have to inherit your class from AsyncRepository.

```
# MODULES
from typing import Callable, List, Optional, Tuple

# SQLALCHEMY
from sqlalchemy import Sequence
from sqlalchemy.ext.asyncio import AsyncSession

# PYSQL_REPO
from pysql_repo import Operators
from pysql_repo.asyncio import AsyncRepository

# CONTEXTLIB
from contextlib import AbstractAsyncContextManager

# MODEL
from tests.repositories.user._base import UserRepositoryBase as _UserRepositoryBase
from tests.models.database.database import User
from tests.models.schemas.user import UserCreate


class AsyncUserRepository(AsyncRepository, _UserRepositoryBase):
    def __init__(
        self,
        session_factory: Callable[..., AbstractAsyncContextManager[AsyncSession]],
    ) -> None:
        super().__init__(session_factory)

    async def get_all(
        self,
        __session__: AsyncSession,
        /,
        ids_in: Optional[List[int]] = None,
        ids_not_in: Optional[List[int]] = None,
        emails_iin: Optional[List[str]] = None,
        emails_in: Optional[List[str]] = None,
        emails_not_iin: Optional[List[str]] = None,
        emails_not_in: Optional[List[str]] = None,
        email_ilike: Optional[str] = None,
        email_like: Optional[str] = None,
        email_not_ilike: Optional[str] = None,
        email_not_like: Optional[str] = None,
        email_equal: Optional[str] = None,
        email_iequal: Optional[str] = None,
        email_different: Optional[str] = None,
        email_idifferent: Optional[str] = None,
        zip_codes_in: Optional[List[int]] = None,
        zip_codes_not_in: Optional[List[int]] = None,
        is_active_equal: Optional[bool] = None,
        load_addresses: bool = True,
        load_city: bool = True,
        order_by: Optional[List[str]] = None,
        direction: Optional[List[str]] = None,
    ) -> Sequence[User]:
        users = await self._select_all(
            __session__,
            model=User,
            optional_filters=self.get_filters(
                ids_in=ids_in,
                ids_not_in=ids_not_in,
                emails_iin=emails_iin,
                emails_in=emails_in,
                emails_not_iin=emails_not_iin,
                emails_not_in=emails_not_in,
                email_ilike=email_ilike,
                email_like=email_like,
                email_not_ilike=email_not_ilike,
                email_not_like=email_not_like,
                email_equal=email_equal,
                email_iequal=email_iequal,
                email_different=email_different,
                email_idifferent=email_idifferent,
                zip_codes_in=zip_codes_in,
                zip_codes_not_in=zip_codes_not_in,
                is_active_equal=is_active_equal,
            ),
            relationship_options=self.get_relationship_options(
                load_addresses=load_addresses,
                load_city=load_city,
                zip_codes_in=zip_codes_in,
                zip_codes_not_in=zip_codes_not_in,
            ),
            order_by=order_by,
            direction=direction,
        )

        return users

    async def get_paginate(
        self,
        __session__: AsyncSession,
        /,
        page: int,
        per_page: int,
        ids_in: Optional[List[int]] = None,
        ids_not_in: Optional[List[int]] = None,
        emails_iin: Optional[List[str]] = None,
        emails_in: Optional[List[str]] = None,
        emails_not_iin: Optional[List[str]] = None,
        emails_not_in: Optional[List[str]] = None,
        email_ilike: Optional[str] = None,
        email_like: Optional[str] = None,
        email_not_ilike: Optional[str] = None,
        email_not_like: Optional[str] = None,
        email_equal: Optional[str] = None,
        email_iequal: Optional[str] = None,
        email_different: Optional[str] = None,
        email_idifferent: Optional[str] = None,
        zip_codes_in: Optional[List[int]] = None,
        zip_codes_not_in: Optional[List[int]] = None,
        is_active_equal: Optional[bool] = None,
        load_addresses: bool = True,
        load_city: bool = True,
        order_by: Optional[List[str]] = None,
        direction: Optional[List[str]] = None,
    ) -> Tuple[Sequence[User], str]:
        users, pagination = await self._select_paginate(
            __session__,
            model=User,
            optional_filters=self.get_filters(
                ids_in=ids_in,
                ids_not_in=ids_not_in,
                emails_iin=emails_iin,
                emails_in=emails_in,
                emails_not_iin=emails_not_iin,
                emails_not_in=emails_not_in,
                email_ilike=email_ilike,
                email_like=email_like,
                email_not_ilike=email_not_ilike,
                email_not_like=email_not_like,
                email_equal=email_equal,
                email_iequal=email_iequal,
                email_different=email_different,
                email_idifferent=email_idifferent,
                zip_codes_in=zip_codes_in,
                zip_codes_not_in=zip_codes_not_in,
                is_active_equal=is_active_equal,
            ),
            relationship_options=self.get_relationship_options(
                load_addresses=load_addresses,
                load_city=load_city,
                zip_codes_in=zip_codes_in,
                zip_codes_not_in=zip_codes_not_in,
            ),
            order_by=order_by,
            direction=direction,
            page=page,
            per_page=per_page,
        )

        return users, pagination

    async def get_by_id(
        self,
        __session__: AsyncSession,
        /,
        id: int,
    ) -> Optional[User]:
        user = await self._select(
            __session__,
            model=User,
            filters={
                User.id: {
                    Operators.EQUAL: id,
                },
            },
        )

        return user

    async def create(
        self,
        __session__: AsyncSession,
        /,
        data: UserCreate,
        flush: bool = False,
        commit: bool = True,
    ) -> User:
        user = await self._add(
            __session__,
            model=User,
            values={
                User.email.key: data.email,
                User.hashed_password.key: data.hashed_password,
                User.full_name.key: data.full_name,
            },
            flush=flush,
            commit=commit,
        )

        return user

    async def create_all(
        self,
        __session__: AsyncSession,
        /,
        data: List[UserCreate],
        flush: bool = False,
        commit: bool = True,
    ) -> Sequence[User]:
        users = await self._add_all(
            __session__,
            model=User,
            values=[
                {
                    User.email.key: item.email,
                    User.hashed_password.key: item.hashed_password,
                    User.full_name.key: item.full_name,
                }
                for item in data
            ],
            flush=flush,
            commit=commit,
        )

        return users

    async def patch_email(
        self,
        __session__: AsyncSession,
        /,
        id: int,
        email: str,
        flush: bool = False,
        commit: bool = True,
    ) -> Optional[User]:
        user = await self._update(
            __session__,
            model=User,
            values={
                User.email.key: email,
            },
            filters={
                User.id: {
                    Operators.EQUAL: id,
                },
            },
            flush=flush,
            commit=commit,
        )

        return user

    async def bulk_patch_email(
        self,
        __session__: AsyncSession,
        /,
        data: List[Tuple[int, str]],
        flush: bool = False,
        commit: bool = True,
    ) -> Sequence[User]:
        await self._bulk_update(
            __session__,
            model=User,
            values=[
                {
                    User.id.key: id,
                    User.email.key: email,
                }
                for id, email in data
            ],
            flush=flush,
            commit=commit,
        )

        return await self._select_all(
            __session__,
            model=User,
            filters={
                User.id: {
                    Operators.IN: [id for id, _ in data],
                },
            },
        )

    async def patch_disable(
        self,
        __session__: AsyncSession,
        /,
        ids: List[int],
        flush: bool = False,
        commit: bool = True,
    ) -> Sequence[User]:
        users = await self._update_all(
            __session__,
            model=User,
            values={
                User.is_active.key: False,
            },
            filters={
                User.id: {
                    Operators.IN: ids,
                },
            },
            flush=flush,
            commit=commit,
        )

        return users

    async def delete(
        self,
        __session__: AsyncSession,
        /,
        id: int,
        flush: bool = False,
        commit: bool = True,
    ) -> bool:
        is_deleted = await self._delete(
            __session__,
            model=User,
            filters={
                User.id: {
                    Operators.EQUAL: id,
                },
            },
            flush=flush,
            commit=commit,
        )

        return is_deleted

    async def delete_all(
        self,
        __session__: AsyncSession,
        /,
        ids: List[int],
        flush: bool = False,
        commit: bool = True,
    ) -> bool:
        is_deleted = await self._delete_all(
            __session__,
            model=User,
            filters={
                User.id: {
                    Operators.IN: ids,
                },
            },
            flush=flush,
            commit=commit,
        )

        return is_deleted
```

To create an async service, you just have to inherit your class from AsyncService.

```
# MODULES
from logging import Logger
from typing import List, Optional, Tuple

# SQLALCHEMY
from sqlalchemy.ext.asyncio import AsyncSession

# PYSQL_REPO
from pysql_repo.asyncio import AsyncService, with_async_session

# REPOSITORIES
from tests.repositories.user.async_user_repository import AsyncUserRepository

# MODELS
from tests.models.schemas.user import UserCreate, UserRead


class AsyncUserService(AsyncService[AsyncUserRepository]):
    def __init__(
        self,
        user_repository: AsyncUserRepository,
        logger: Logger,
    ) -> None:
        super().__init__(
            repository=user_repository,
        )
        self._logger = logger

    async def get_users(
        self,
        __session__: AsyncSession,
        /,
        ids_in: Optional[List[int]] = None,
        ids_not_in: Optional[List[int]] = None,
        emails_iin: Optional[List[str]] = None,
        emails_in: Optional[List[str]] = None,
        emails_not_iin: Optional[List[str]] = None,
        emails_not_in: Optional[List[str]] = None,
        email_ilike: Optional[str] = None,
        email_like: Optional[str] = None,
        email_not_ilike: Optional[str] = None,
        email_not_like: Optional[str] = None,
        email_equal: Optional[str] = None,
        email_iequal: Optional[str] = None,
        email_different: Optional[str] = None,
        email_idifferent: Optional[str] = None,
        zip_codes_in: Optional[List[int]] = None,
        zip_codes_not_in: Optional[List[int]] = None,
        is_active_equal: Optional[bool] = None,
        load_addresses: bool = True,
        load_city: bool = True,
        order_by: Optional[List[str]] = None,
        direction: Optional[List[str]] = None,
    ) -> List[UserRead]:
        users = await self._repository.get_all(
            __session__,
            ids_in=ids_in,
            ids_not_in=ids_not_in,
            emails_iin=emails_iin,
            emails_in=emails_in,
            emails_not_iin=emails_not_iin,
            emails_not_in=emails_not_in,
            email_ilike=email_ilike,
            email_like=email_like,
            email_not_ilike=email_not_ilike,
            email_not_like=email_not_like,
            email_equal=email_equal,
            email_iequal=email_iequal,
            email_different=email_different,
            email_idifferent=email_idifferent,
            zip_codes_in=zip_codes_in,
            zip_codes_not_in=zip_codes_not_in,
            is_active_equal=is_active_equal,
            load_addresses=load_addresses,
            load_city=load_city,
            order_by=order_by,
            direction=direction,
        )

        return [UserRead.model_validate(item) for item in users]

    async def get_users_paginate(
        self,
        __session__: AsyncSession,
        /,
        page: int,
        per_page: int,
        ids_in: Optional[List[int]] = None,
        ids_not_in: Optional[List[int]] = None,
        emails_iin: Optional[List[str]] = None,
        emails_in: Optional[List[str]] = None,
        emails_not_iin: Optional[List[str]] = None,
        emails_not_in: Optional[List[str]] = None,
        email_ilike: Optional[str] = None,
        email_like: Optional[str] = None,
        email_not_ilike: Optional[str] = None,
        email_not_like: Optional[str] = None,
        email_equal: Optional[str] = None,
        email_iequal: Optional[str] = None,
        email_different: Optional[str] = None,
        email_idifferent: Optional[str] = None,
        zip_codes_in: Optional[List[int]] = None,
        zip_codes_not_in: Optional[List[int]] = None,
        is_active_equal: Optional[bool] = None,
        load_addresses: bool = True,
        load_city: bool = True,
        order_by: Optional[List[str]] = None,
        direction: Optional[List[str]] = None,
    ) -> Tuple[List[UserRead], str]:
        users, pagination = await self._repository.get_paginate(
            __session__,
            page=page,
            per_page=per_page,
            ids_in=ids_in,
            ids_not_in=ids_not_in,
            emails_iin=emails_iin,
            emails_in=emails_in,
            emails_not_iin=emails_not_iin,
            emails_not_in=emails_not_in,
            email_ilike=email_ilike,
            email_like=email_like,
            email_not_ilike=email_not_ilike,
            email_not_like=email_not_like,
            email_equal=email_equal,
            email_iequal=email_iequal,
            email_different=email_different,
            email_idifferent=email_idifferent,
            zip_codes_in=zip_codes_in,
            zip_codes_not_in=zip_codes_not_in,
            is_active_equal=is_active_equal,
            load_addresses=load_addresses,
            load_city=load_city,
            order_by=order_by,
            direction=direction,
        )

        return [UserRead.model_validate(item) for item in users], pagination

    async def get_user_by_id(
        self,
        __session__: AsyncSession,
        /,
        id: int,
    ) -> Optional[UserRead]:
        user = await self._repository.get_by_id(
            __session__,
            id=id,
        )

        if user is None:
            return None

        return UserRead.model_validate(user)

    async def create_user(
        self,
        __session__: AsyncSession,
        /,
        data: UserCreate,
    ) -> UserRead:
        user = await self._repository.create(
            __session__,
            data=data,
            flush=True,
        )

        return UserRead.model_validate(user)

    async def create_users(
        self,
        __session__: AsyncSession,
        /,
        data: List[UserCreate],
    ) -> List[UserRead]:
        users = await self._repository.create_all(
            __session__,
            data=data,
            flush=True,
        )

        return [UserRead.model_validate(user) for user in users]

    async def patch_email(
        self,
        __session__: AsyncSession,
        /,
        id: int,
        email: str,
    ) -> UserRead:
        user = await self._repository.patch_email(
            __session__,
            id=id,
            email=email,
            flush=True,
        )

        return UserRead.model_validate(user)

    async def bulk_patch_email(
        self,
        __session__: AsyncSession,
        /,
        data: List[Tuple[int, str]],
    ) -> List[UserRead]:
        users = await self._repository.bulk_patch_email(
            __session__,
            data=data,
            flush=True,
        )

        return [UserRead.model_validate(user) for user in users]

    async def patch_disable(
        self,
        __session__: AsyncSession,
        /,
        ids: List[int],
    ) -> List[UserRead]:
        users = await self._repository.patch_disable(
            __session__,
            ids=ids,
            flush=True,
        )

        return [UserRead.model_validate(user) for user in users]

    async def delete_by_id(
        self,
        __session__: AsyncSession,
        /,
        id: int,
    ) -> bool:
        return await self._repository.delete(
            __session__,
            id=id,
            flush=True,
        )

    async def delete_by_ids(
        self,
        __session__: AsyncSession,
        /,
        ids: List[int],
    ) -> bool:
        return await self._repository.delete_all(
            __session__,
            ids=ids,
            flush=True,
        )

```

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/Impro02/pysql-repo",
    "name": "pysql-repo",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.8",
    "maintainer_email": null,
    "keywords": null,
    "author": "Maxime MARTIN",
    "author_email": "Maxime MARTIN <maxime.martin02@hotmail.fr>",
    "download_url": "https://files.pythonhosted.org/packages/48/19/bacf94b17a2352cf8dd736da1b6e6ff1170aa584787031380bf816a8ca28/pysql-repo-0.7.4.0.tar.gz",
    "platform": null,
    "description": "The pysql-repo library is a Python library that is designed to use the session/repository pattern to interact with databases in Python projects. It provides a more flexible notation for running SQL queries and is built on top of SQLAlchemy, a popular Python SQL toolkit. With pysql_repo, users can write SQL queries using a new, more intuitive syntax, simplifying the process of working with SQL databases in Python and making it easier to write and maintain complex queries.\n\n## Installing pysql-repo\n\nTo install pysql-repo, if you already have Python, you can install with:\n\n```\npip install pysql_repo\n```\n\n## How to import pysql-repo\n\nTo access pysql-repo and its functions import it in your Python code like this:\n\n```\nfrom pysql_repo import Database, Repository, Service, with_session, Operators, LoadingTechnique, RelationshipOption\n```\n\nTo access pysql-repo and its asyncio functions import it in your Python code like this:\n\n```\nfrom pysql_repo.asyncio import AsyncDatabase, AsyncRepository, AsyncService, with_async_session\n```\n\n## Reading the example code\n\n```\n# MODULES\nfrom typing import List\n\n# SQLALCHEMY\nfrom sqlalchemy import Boolean, ForeignKey, Integer, String\nfrom sqlalchemy.orm import relationship, Mapped, mapped_column\nfrom sqlalchemy.ext.declarative import declarative_base\n\nBase = declarative_base()\n\n\nclass City(Base):\n    __tablename__ = \"CITY\"\n\n    id: Mapped[int] = mapped_column(\n        \"ID\",\n        Integer,\n        primary_key=True,\n        index=True,\n    )\n    name: Mapped[str] = mapped_column(\n        \"NAME\",\n        String,\n        index=True,\n    )\n    state: Mapped[str] = mapped_column(\n        \"STATE\",\n        String,\n        index=True,\n    )\n\n    addresses: Mapped[List[\"Address\"]] = relationship(\n        \"Address\",\n        back_populates=\"city\",\n        lazy=\"joined\",\n        cascade=\"all, delete-orphan\",\n    )\n\n\nclass Address(Base):\n    __tablename__ = \"ADDRESS\"\n\n    id: Mapped[int] = mapped_column(\n        \"ID\",\n        Integer,\n        primary_key=True,\n        index=True,\n    )\n    street: Mapped[str] = mapped_column(\n        \"STREET\",\n        String,\n        index=True,\n    )\n    zip_code: Mapped[str] = mapped_column(\n        \"ZIP_CODE\",\n        Integer,\n        index=True,\n    )\n    user_id: Mapped[int] = mapped_column(\n        \"USER_ID\",\n        Integer,\n        ForeignKey(\"USER.ID\"),\n    )\n    city_id: Mapped[int] = mapped_column(\n        \"CITY_ID\",\n        Integer,\n        ForeignKey(\"CITY.ID\"),\n    )\n\n    user: Mapped[\"User\"] = relationship(\n        \"User\",\n        back_populates=\"addresses\",\n        lazy=\"joined\",\n    )\n    city: Mapped[\"City\"] = relationship(\n        \"City\",\n        back_populates=\"addresses\",\n        lazy=\"joined\",\n    )\n\n\nclass User(Base):\n    __tablename__ = \"USER\"\n\n    id: Mapped[int] = mapped_column(\n        \"ID\",\n        Integer,\n        primary_key=True,\n        index=True,\n    )\n    email: Mapped[str] = mapped_column(\n        \"EMAIL\",\n        String,\n        unique=True,\n        index=True,\n    )\n    hashed_password: Mapped[str] = mapped_column(\n        \"HASHED_PASSWORD\",\n        String,\n    )\n    full_name: Mapped[str] = mapped_column(\n        \"FULL_NAME\",\n        String,\n        index=True,\n    )\n    is_active: Mapped[bool] = mapped_column(\n        \"IS_ACTIVE\",\n        Boolean,\n        default=True,\n    )\n\n    addresses: Mapped[List[\"Address\"]] = relationship(\n        \"Address\",\n        back_populates=\"user\",\n        lazy=\"joined\",\n        cascade=\"all, delete-orphan\",\n    )\n```\n\nTo create an instance of Database and generate an instance of Session from the factory:\n\n```\nimport logging\n\nlogging.basicConfig()\nlogger_db = logging.get_logger('demo')\n\ndatabase = DataBase(\n    databases_config={\n        \"connection_string\": \"foo\",\n    },\n    base=Base,\n    logger=logger_db,\n)\n\ndatabase.create_database()\n\nwith database.session_factory() as session:\n    session.execute(...)\n```\n\nTo create a repository, you just have to inherit your class from Repository.\n\n```\n# MODULES\nfrom typing import Any, Callable, Dict, List, Optional, Sequence, Tuple\n\n# SQLALCHEMY\nfrom sqlalchemy.orm import Column, Session\n\n# PYSQL_REPO\nfrom pysql_repo import Operators, Repository, LoadingTechnique, RelationshipOption\n\n# CONTEXTLIB\nfrom contextlib import AbstractContextManager\n\n# MODEL\nfrom tests.repositories.user._base import UserRepositoryBase as _UserRepositoryBase\nfrom tests.models.database.database import Address, User\nfrom tests.models.schemas.user import UserCreate\n\n\nclass UserRepositoryBase:\n    @classmethod\n    def get_filters(\n        cls,\n        ids_in: Optional[List[int]] = None,\n        ids_not_in: Optional[List[int]] = None,\n        emails_iin: Optional[List[str]] = None,\n        emails_in: Optional[List[str]] = None,\n        emails_not_iin: Optional[List[str]] = None,\n        emails_not_in: Optional[List[str]] = None,\n        email_ilike: Optional[List[str]] = None,\n        email_like: Optional[List[str]] = None,\n        email_not_ilike: Optional[List[str]] = None,\n        email_not_like: Optional[List[str]] = None,\n        email_equal: Optional[str] = None,\n        email_iequal: Optional[str] = None,\n        email_different: Optional[str] = None,\n        email_idifferent: Optional[str] = None,\n        zip_codes_in: Optional[List[str]] = None,\n        zip_codes_not_in: Optional[List[str]] = None,\n        is_active_equal: Optional[bool] = None,\n    ) -> Dict[Column, Any]:\n        return {\n            User.id: {\n                Operators.IN: ids_in,\n                Operators.NOT_IN: ids_not_in,\n            },\n            User.email: {\n                Operators.IIN: emails_iin,\n                Operators.IN: emails_in,\n                Operators.NOT_IIN: emails_not_iin,\n                Operators.NOT_IN: emails_not_in,\n                Operators.ILIKE: email_ilike,\n                Operators.LIKE: email_like,\n                Operators.NOT_ILIKE: email_not_ilike,\n                Operators.NOT_LIKE: email_not_like,\n                Operators.EQUAL: email_equal,\n                Operators.IEQUAL: email_iequal,\n                Operators.DIFFERENT: email_different,\n                Operators.IDIFFERENT: email_idifferent,\n            },\n            User.is_active: {\n                Operators.EQUAL: is_active_equal,\n            },\n            User.addresses: {\n                Operators.ANY: {\n                    Address.zip_code: {\n                        Operators.IN: zip_codes_in,\n                        Operators.NOT_IN: zip_codes_not_in,\n                    },\n                }\n            },\n        }\n\n    @classmethod\n    def get_relationship_options(\n        cls,\n        load_addresses: bool = False,\n        load_city: bool = False,\n        zip_codes_not_in: Optional[List[int]] = None,\n        zip_codes_in: Optional[List[int]] = None,\n    ):\n        extra_join_addresses = []\n        if zip_codes_not_in:\n            extra_join_addresses.append(Address.zip_code.not_in(zip_codes_not_in))\n        if zip_codes_in:\n            extra_join_addresses.append(Address.zip_code.in_(zip_codes_in))\n\n        return {\n            User.addresses: RelationshipOption(\n                lazy=LoadingTechnique.JOINED\n                if load_addresses\n                else LoadingTechnique.NOLOAD,\n                added_criteria=extra_join_addresses\n                if len(extra_join_addresses) > 0\n                else None,\n                children={\n                    Address.city: RelationshipOption(\n                        lazy=LoadingTechnique.JOINED\n                        if load_city\n                        else LoadingTechnique.NOLOAD,\n                    )\n                },\n            ),\n        }\n\n\nclass UserRepository(Repository, _UserRepositoryBase):\n    def __init__(\n        self,\n        session_factory: Callable[..., AbstractContextManager[Session]],\n    ) -> None:\n        super().__init__(session_factory)\n\n    def get_all(\n        self,\n        __session__: Session,\n        /,\n        ids_in: Optional[List[int]] = None,\n        ids_not_in: Optional[List[int]] = None,\n        emails_iin: Optional[List[str]] = None,\n        emails_in: Optional[List[str]] = None,\n        emails_not_iin: Optional[List[str]] = None,\n        emails_not_in: Optional[List[str]] = None,\n        email_ilike: Optional[str] = None,\n        email_like: Optional[str] = None,\n        email_not_ilike: Optional[str] = None,\n        email_not_like: Optional[str] = None,\n        email_equal: Optional[str] = None,\n        email_iequal: Optional[str] = None,\n        email_different: Optional[str] = None,\n        email_idifferent: Optional[str] = None,\n        zip_codes_in: Optional[List[int]] = None,\n        zip_codes_not_in: Optional[List[int]] = None,\n        is_active_equal: Optional[bool] = None,\n        load_addresses: bool = True,\n        load_city: bool = True,\n        order_by: Optional[List[str]] = None,\n        direction: Optional[List[str]] = None,\n    ) -> Sequence[User]:\n        users = self._select_all(\n            __session__,\n            model=User,\n            optional_filters=self.get_filters(\n                ids_in=ids_in,\n                ids_not_in=ids_not_in,\n                emails_iin=emails_iin,\n                emails_in=emails_in,\n                emails_not_iin=emails_not_iin,\n                emails_not_in=emails_not_in,\n                email_ilike=email_ilike,\n                email_like=email_like,\n                email_not_ilike=email_not_ilike,\n                email_not_like=email_not_like,\n                email_equal=email_equal,\n                email_iequal=email_iequal,\n                email_different=email_different,\n                email_idifferent=email_idifferent,\n                zip_codes_in=zip_codes_in,\n                zip_codes_not_in=zip_codes_not_in,\n                is_active_equal=is_active_equal,\n            ),\n            relationship_options=self.get_relationship_options(\n                load_addresses=load_addresses,\n                load_city=load_city,\n                zip_codes_in=zip_codes_in,\n                zip_codes_not_in=zip_codes_not_in,\n            ),\n            order_by=order_by,\n            direction=direction,\n        )\n\n        return users\n\n    def get_paginate(\n        self,\n        __session__: Session,\n        /,\n        page: int,\n        per_page: int,\n        ids_in: Optional[List[int]] = None,\n        ids_not_in: Optional[List[int]] = None,\n        emails_iin: Optional[List[str]] = None,\n        emails_in: Optional[List[str]] = None,\n        emails_not_iin: Optional[List[str]] = None,\n        emails_not_in: Optional[List[str]] = None,\n        email_ilike: Optional[str] = None,\n        email_like: Optional[str] = None,\n        email_not_ilike: Optional[str] = None,\n        email_not_like: Optional[str] = None,\n        email_equal: Optional[str] = None,\n        email_iequal: Optional[str] = None,\n        email_different: Optional[str] = None,\n        email_idifferent: Optional[str] = None,\n        zip_codes_in: Optional[List[int]] = None,\n        zip_codes_not_in: Optional[List[int]] = None,\n        is_active_equal: Optional[bool] = None,\n        load_addresses: bool = True,\n        load_city: bool = True,\n        order_by: Optional[List[str]] = None,\n        direction: Optional[List[str]] = None,\n    ) -> Tuple[Sequence[User], str]:\n        users, pagination = self._select_paginate(\n            __session__,\n            model=User,\n            optional_filters=self.get_filters(\n                ids_in=ids_in,\n                ids_not_in=ids_not_in,\n                emails_iin=emails_iin,\n                emails_in=emails_in,\n                emails_not_iin=emails_not_iin,\n                emails_not_in=emails_not_in,\n                email_ilike=email_ilike,\n                email_like=email_like,\n                email_not_ilike=email_not_ilike,\n                email_not_like=email_not_like,\n                email_equal=email_equal,\n                email_iequal=email_iequal,\n                email_different=email_different,\n                email_idifferent=email_idifferent,\n                zip_codes_in=zip_codes_in,\n                zip_codes_not_in=zip_codes_not_in,\n                is_active_equal=is_active_equal,\n            ),\n            relationship_options=self.get_relationship_options(\n                load_addresses=load_addresses,\n                load_city=load_city,\n                zip_codes_in=zip_codes_in,\n                zip_codes_not_in=zip_codes_not_in,\n            ),\n            order_by=order_by,\n            direction=direction,\n            page=page,\n            per_page=per_page,\n        )\n\n        return users, pagination\n\n    def get_by_id(\n        self,\n        __session__: Session,\n        id: int,\n    ) -> Optional[User]:\n        user = self._select(\n            __session__,\n            model=User,\n            filters={\n                User.id: {\n                    Operators.EQUAL: id,\n                },\n            },\n        )\n\n        return user\n\n    def create(\n        self,\n        __session__: Session,\n        /,\n        data: UserCreate,\n        flush: bool = False,\n        commit: bool = True,\n    ) -> User:\n        user = self._add(\n            __session__,\n            model=User,\n            values={\n                User.email.key: data.email,\n                User.hashed_password.key: data.hashed_password,\n                User.full_name.key: data.full_name,\n            },\n            flush=flush,\n            commit=commit,\n        )\n\n        return user\n\n    def create_all(\n        self,\n        __session__: Session,\n        /,\n        data: List[UserCreate],\n        flush: bool = False,\n        commit: bool = True,\n    ) -> Sequence[User]:\n        users = self._add_all(\n            __session__,\n            model=User,\n            values=[\n                {\n                    User.email.key: item.email,\n                    User.hashed_password.key: item.hashed_password,\n                    User.full_name.key: item.full_name,\n                }\n                for item in data\n            ],\n            flush=flush,\n            commit=commit,\n        )\n\n        return users\n\n    def patch_email(\n        self,\n        __session__: Session,\n        /,\n        id: int,\n        email: str,\n        flush: bool = False,\n        commit: bool = True,\n    ) -> Optional[User]:\n        user = self._update(\n            __session__,\n            model=User,\n            values={\n                User.email.key: email,\n            },\n            filters={\n                User.id: {\n                    Operators.EQUAL: id,\n                },\n            },\n            flush=flush,\n            commit=commit,\n        )\n\n        return user\n\n    def bulk_patch_email(\n        self,\n        __session__: Session,\n        /,\n        data: List[Tuple[int, str]],\n        flush: bool = False,\n        commit: bool = True,\n    ) -> Sequence[User]:\n        self._bulk_update(\n            __session__,\n            model=User,\n            values=[\n                {\n                    User.id.key: id,\n                    User.email.key: email,\n                }\n                for id, email in data\n            ],\n            flush=flush,\n            commit=commit,\n        )\n\n        return self._select_all(\n            __session__,\n            model=User,\n            filters={\n                User.id: {\n                    Operators.IN: [id for id, _ in data],\n                },\n            },\n        )\n\n    def patch_disable(\n        self,\n        __session__: Session,\n        /,\n        ids: List[int],\n        flush: bool = False,\n        commit: bool = True,\n    ) -> Sequence[User]:\n        users = self._update_all(\n            __session__,\n            model=User,\n            values={\n                User.is_active.key: False,\n            },\n            filters={\n                User.id: {\n                    Operators.IN: ids,\n                },\n            },\n            flush=flush,\n            commit=commit,\n        )\n\n        return users\n\n    def delete(\n        self,\n        __session__: Session,\n        /,\n        id: int,\n        flush: bool = False,\n        commit: bool = True,\n    ) -> bool:\n        is_deleted = self._delete(\n            __session__,\n            model=User,\n            filters={\n                User.id: {\n                    Operators.EQUAL: id,\n                },\n            },\n            flush=flush,\n            commit=commit,\n        )\n\n        return is_deleted\n\n    def delete_all(\n        self,\n        __session__: Session,\n        /,\n        ids: List[int],\n        flush: bool = False,\n        commit: bool = True,\n    ) -> bool:\n        is_deleted = self._delete_all(\n            __session__,\n            model=User,\n            filters={\n                User.id: {\n                    Operators.IN: ids,\n                },\n            },\n            flush=flush,\n            commit=commit,\n        )\n\n        return is_deleted\n```\n\nTo create a service, you just have to inherit your class from Service.\n\n```\n# MODULES\nfrom logging import Logger\nfrom typing import List, Optional, Tuple\n\n# SQLALCHEMY\nfrom sqlalchemy.orm import Session\n\n# PYSQL_REPO\nfrom pysql_repo import Service, with_session\n\n# REPOSITORIES\nfrom tests.repositories.user.user_repository import UserRepository\n\n# MODELS\nfrom tests.models.schemas.user import UserCreate, UserRead\n\n\nclass UserService(Service[UserRepository]):\n    def __init__(\n        self,\n        user_repository: UserRepository,\n        logger: Logger,\n    ) -> None:\n        super().__init__(\n            repository=user_repository,\n        )\n        self._logger = logger\n\n    def get_users(\n        self,\n        __session__: Session,\n        /,\n        ids_in: Optional[List[int]] = None,\n        ids_not_in: Optional[List[int]] = None,\n        emails_iin: Optional[List[str]] = None,\n        emails_in: Optional[List[str]] = None,\n        emails_not_iin: Optional[List[str]] = None,\n        emails_not_in: Optional[List[str]] = None,\n        email_ilike: Optional[str] = None,\n        email_like: Optional[str] = None,\n        email_not_ilike: Optional[str] = None,\n        email_not_like: Optional[str] = None,\n        email_equal: Optional[str] = None,\n        email_iequal: Optional[str] = None,\n        email_different: Optional[str] = None,\n        email_idifferent: Optional[str] = None,\n        zip_codes_in: Optional[List[int]] = None,\n        zip_codes_not_in: Optional[List[int]] = None,\n        is_active_equal: Optional[bool] = None,\n        load_addresses: bool = True,\n        load_city: bool = True,\n        order_by: Optional[List[str]] = None,\n        direction: Optional[List[str]] = None,\n    ) -> List[UserRead]:\n        users = self._repository.get_all(\n            __session__,\n            ids_in=ids_in,\n            ids_not_in=ids_not_in,\n            emails_iin=emails_iin,\n            emails_in=emails_in,\n            emails_not_iin=emails_not_iin,\n            emails_not_in=emails_not_in,\n            email_ilike=email_ilike,\n            email_like=email_like,\n            email_not_ilike=email_not_ilike,\n            email_not_like=email_not_like,\n            email_equal=email_equal,\n            email_iequal=email_iequal,\n            email_different=email_different,\n            email_idifferent=email_idifferent,\n            zip_codes_in=zip_codes_in,\n            zip_codes_not_in=zip_codes_not_in,\n            is_active_equal=is_active_equal,\n            load_addresses=load_addresses,\n            load_city=load_city,\n            order_by=order_by,\n            direction=direction,\n        )\n\n        return [UserRead.model_validate(item) for item in users]\n\n    def get_users_paginate(\n        self,\n        __session__: Session,\n        /,\n        page: int,\n        per_page: int,\n        ids_in: Optional[List[int]] = None,\n        ids_not_in: Optional[List[int]] = None,\n        emails_iin: Optional[List[str]] = None,\n        emails_in: Optional[List[str]] = None,\n        emails_not_iin: Optional[List[str]] = None,\n        emails_not_in: Optional[List[str]] = None,\n        email_ilike: Optional[str] = None,\n        email_like: Optional[str] = None,\n        email_not_ilike: Optional[str] = None,\n        email_not_like: Optional[str] = None,\n        email_equal: Optional[str] = None,\n        email_iequal: Optional[str] = None,\n        email_different: Optional[str] = None,\n        email_idifferent: Optional[str] = None,\n        zip_codes_in: Optional[List[int]] = None,\n        zip_codes_not_in: Optional[List[int]] = None,\n        is_active_equal: Optional[bool] = None,\n        load_addresses: bool = True,\n        load_city: bool = True,\n        order_by: Optional[List[str]] = None,\n        direction: Optional[List[str]] = None,\n    ) -> Tuple[List[UserRead], str]:\n        users, pagination = self._repository.get_paginate(\n            __session__,\n            page=page,\n            per_page=per_page,\n            ids_in=ids_in,\n            ids_not_in=ids_not_in,\n            emails_iin=emails_iin,\n            emails_in=emails_in,\n            emails_not_iin=emails_not_iin,\n            emails_not_in=emails_not_in,\n            email_ilike=email_ilike,\n            email_like=email_like,\n            email_not_ilike=email_not_ilike,\n            email_not_like=email_not_like,\n            email_equal=email_equal,\n            email_iequal=email_iequal,\n            email_different=email_different,\n            email_idifferent=email_idifferent,\n            zip_codes_in=zip_codes_in,\n            zip_codes_not_in=zip_codes_not_in,\n            is_active_equal=is_active_equal,\n            load_addresses=load_addresses,\n            load_city=load_city,\n            order_by=order_by,\n            direction=direction,\n        )\n\n        return [UserRead.model_validate(item) for item in users], pagination\n\n    def get_user_by_id(\n        self,\n        __session__: Session,\n        /,\n        id: int,\n    ) -> Optional[UserRead]:\n        user = self._repository.get_by_id(\n            __session__,\n            id=id,\n        )\n\n        if user is None:\n            return None\n\n        return UserRead.model_validate(user)\n\n    def create_user(\n        self,\n        __session__: Session,\n        /,\n        data: UserCreate,\n    ) -> UserRead:\n        user = self._repository.create(\n            __session__,\n            data=data,\n            flush=True,\n        )\n\n        return UserRead.model_validate(user)\n\n    def create_users(\n        self,\n        __session__: Session,\n        /,\n        data: List[UserCreate],\n    ) -> List[UserRead]:\n        users = self._repository.create_all(\n            __session__,\n            data=data,\n            flush=True,\n        )\n\n        return [UserRead.model_validate(user) for user in users]\n\n    def patch_email(\n        self,\n        __session__: Session,\n        /,\n        id: int,\n        email: str,\n    ) -> UserRead:\n        user = self._repository.patch_email(\n            __session__,\n            id=id,\n            email=email,\n            flush=True,\n        )\n\n        return UserRead.model_validate(user)\n\n    def bulk_patch_email(\n        self,\n        __session__: Session,\n        /,\n        data: List[Tuple[int, str]],\n    ) -> List[UserRead]:\n        users = self._repository.bulk_patch_email(\n            __session__,\n            data=data,\n            flush=True,\n        )\n\n        return [UserRead.model_validate(user) for user in users]\n\n    def patch_disable(\n        self,\n        __session__: Session,\n        /,\n        ids: List[int],\n    ) -> List[UserRead]:\n        users = self._repository.patch_disable(\n            __session__,\n            ids=ids,\n            flush=True,\n        )\n\n        return [UserRead.model_validate(user) for user in users]\n\n    def delete_by_id(\n        self,\n        __session__: Session,\n        /,\n        id: int,\n    ) -> bool:\n        return self._repository.delete(\n            __session__,\n            id=id,\n            flush=True,\n        )\n\n    def delete_by_ids(\n        self,\n        __session__: Session,\n        /,\n        ids: List[int],\n    ) -> bool:\n        return self._repository.delete_all(\n            __session__,\n            ids=ids,\n            flush=True,\n        )\n```\n\nTo create an instance of AsyncDatabase and generate an instance of AsyncSession from the factory:\n\n```\nimport logging\n\nlogging.basicConfig()\nlogger_db = logging.get_logger('demo')\n\ndatabase = AsyncDataBase(\n    databases_config={\n        \"connection_string\": \"foo\",\n    },\n    base=Base,\n    logger=logger_db,\n)\n\nawait database.create_database()\n\nasync with database.session_factory() as session:\n    await session.execute(...)\n```\n\nTo create an async repository, you just have to inherit your class from AsyncRepository.\n\n```\n# MODULES\nfrom typing import Callable, List, Optional, Tuple\n\n# SQLALCHEMY\nfrom sqlalchemy import Sequence\nfrom sqlalchemy.ext.asyncio import AsyncSession\n\n# PYSQL_REPO\nfrom pysql_repo import Operators\nfrom pysql_repo.asyncio import AsyncRepository\n\n# CONTEXTLIB\nfrom contextlib import AbstractAsyncContextManager\n\n# MODEL\nfrom tests.repositories.user._base import UserRepositoryBase as _UserRepositoryBase\nfrom tests.models.database.database import User\nfrom tests.models.schemas.user import UserCreate\n\n\nclass AsyncUserRepository(AsyncRepository, _UserRepositoryBase):\n    def __init__(\n        self,\n        session_factory: Callable[..., AbstractAsyncContextManager[AsyncSession]],\n    ) -> None:\n        super().__init__(session_factory)\n\n    async def get_all(\n        self,\n        __session__: AsyncSession,\n        /,\n        ids_in: Optional[List[int]] = None,\n        ids_not_in: Optional[List[int]] = None,\n        emails_iin: Optional[List[str]] = None,\n        emails_in: Optional[List[str]] = None,\n        emails_not_iin: Optional[List[str]] = None,\n        emails_not_in: Optional[List[str]] = None,\n        email_ilike: Optional[str] = None,\n        email_like: Optional[str] = None,\n        email_not_ilike: Optional[str] = None,\n        email_not_like: Optional[str] = None,\n        email_equal: Optional[str] = None,\n        email_iequal: Optional[str] = None,\n        email_different: Optional[str] = None,\n        email_idifferent: Optional[str] = None,\n        zip_codes_in: Optional[List[int]] = None,\n        zip_codes_not_in: Optional[List[int]] = None,\n        is_active_equal: Optional[bool] = None,\n        load_addresses: bool = True,\n        load_city: bool = True,\n        order_by: Optional[List[str]] = None,\n        direction: Optional[List[str]] = None,\n    ) -> Sequence[User]:\n        users = await self._select_all(\n            __session__,\n            model=User,\n            optional_filters=self.get_filters(\n                ids_in=ids_in,\n                ids_not_in=ids_not_in,\n                emails_iin=emails_iin,\n                emails_in=emails_in,\n                emails_not_iin=emails_not_iin,\n                emails_not_in=emails_not_in,\n                email_ilike=email_ilike,\n                email_like=email_like,\n                email_not_ilike=email_not_ilike,\n                email_not_like=email_not_like,\n                email_equal=email_equal,\n                email_iequal=email_iequal,\n                email_different=email_different,\n                email_idifferent=email_idifferent,\n                zip_codes_in=zip_codes_in,\n                zip_codes_not_in=zip_codes_not_in,\n                is_active_equal=is_active_equal,\n            ),\n            relationship_options=self.get_relationship_options(\n                load_addresses=load_addresses,\n                load_city=load_city,\n                zip_codes_in=zip_codes_in,\n                zip_codes_not_in=zip_codes_not_in,\n            ),\n            order_by=order_by,\n            direction=direction,\n        )\n\n        return users\n\n    async def get_paginate(\n        self,\n        __session__: AsyncSession,\n        /,\n        page: int,\n        per_page: int,\n        ids_in: Optional[List[int]] = None,\n        ids_not_in: Optional[List[int]] = None,\n        emails_iin: Optional[List[str]] = None,\n        emails_in: Optional[List[str]] = None,\n        emails_not_iin: Optional[List[str]] = None,\n        emails_not_in: Optional[List[str]] = None,\n        email_ilike: Optional[str] = None,\n        email_like: Optional[str] = None,\n        email_not_ilike: Optional[str] = None,\n        email_not_like: Optional[str] = None,\n        email_equal: Optional[str] = None,\n        email_iequal: Optional[str] = None,\n        email_different: Optional[str] = None,\n        email_idifferent: Optional[str] = None,\n        zip_codes_in: Optional[List[int]] = None,\n        zip_codes_not_in: Optional[List[int]] = None,\n        is_active_equal: Optional[bool] = None,\n        load_addresses: bool = True,\n        load_city: bool = True,\n        order_by: Optional[List[str]] = None,\n        direction: Optional[List[str]] = None,\n    ) -> Tuple[Sequence[User], str]:\n        users, pagination = await self._select_paginate(\n            __session__,\n            model=User,\n            optional_filters=self.get_filters(\n                ids_in=ids_in,\n                ids_not_in=ids_not_in,\n                emails_iin=emails_iin,\n                emails_in=emails_in,\n                emails_not_iin=emails_not_iin,\n                emails_not_in=emails_not_in,\n                email_ilike=email_ilike,\n                email_like=email_like,\n                email_not_ilike=email_not_ilike,\n                email_not_like=email_not_like,\n                email_equal=email_equal,\n                email_iequal=email_iequal,\n                email_different=email_different,\n                email_idifferent=email_idifferent,\n                zip_codes_in=zip_codes_in,\n                zip_codes_not_in=zip_codes_not_in,\n                is_active_equal=is_active_equal,\n            ),\n            relationship_options=self.get_relationship_options(\n                load_addresses=load_addresses,\n                load_city=load_city,\n                zip_codes_in=zip_codes_in,\n                zip_codes_not_in=zip_codes_not_in,\n            ),\n            order_by=order_by,\n            direction=direction,\n            page=page,\n            per_page=per_page,\n        )\n\n        return users, pagination\n\n    async def get_by_id(\n        self,\n        __session__: AsyncSession,\n        /,\n        id: int,\n    ) -> Optional[User]:\n        user = await self._select(\n            __session__,\n            model=User,\n            filters={\n                User.id: {\n                    Operators.EQUAL: id,\n                },\n            },\n        )\n\n        return user\n\n    async def create(\n        self,\n        __session__: AsyncSession,\n        /,\n        data: UserCreate,\n        flush: bool = False,\n        commit: bool = True,\n    ) -> User:\n        user = await self._add(\n            __session__,\n            model=User,\n            values={\n                User.email.key: data.email,\n                User.hashed_password.key: data.hashed_password,\n                User.full_name.key: data.full_name,\n            },\n            flush=flush,\n            commit=commit,\n        )\n\n        return user\n\n    async def create_all(\n        self,\n        __session__: AsyncSession,\n        /,\n        data: List[UserCreate],\n        flush: bool = False,\n        commit: bool = True,\n    ) -> Sequence[User]:\n        users = await self._add_all(\n            __session__,\n            model=User,\n            values=[\n                {\n                    User.email.key: item.email,\n                    User.hashed_password.key: item.hashed_password,\n                    User.full_name.key: item.full_name,\n                }\n                for item in data\n            ],\n            flush=flush,\n            commit=commit,\n        )\n\n        return users\n\n    async def patch_email(\n        self,\n        __session__: AsyncSession,\n        /,\n        id: int,\n        email: str,\n        flush: bool = False,\n        commit: bool = True,\n    ) -> Optional[User]:\n        user = await self._update(\n            __session__,\n            model=User,\n            values={\n                User.email.key: email,\n            },\n            filters={\n                User.id: {\n                    Operators.EQUAL: id,\n                },\n            },\n            flush=flush,\n            commit=commit,\n        )\n\n        return user\n\n    async def bulk_patch_email(\n        self,\n        __session__: AsyncSession,\n        /,\n        data: List[Tuple[int, str]],\n        flush: bool = False,\n        commit: bool = True,\n    ) -> Sequence[User]:\n        await self._bulk_update(\n            __session__,\n            model=User,\n            values=[\n                {\n                    User.id.key: id,\n                    User.email.key: email,\n                }\n                for id, email in data\n            ],\n            flush=flush,\n            commit=commit,\n        )\n\n        return await self._select_all(\n            __session__,\n            model=User,\n            filters={\n                User.id: {\n                    Operators.IN: [id for id, _ in data],\n                },\n            },\n        )\n\n    async def patch_disable(\n        self,\n        __session__: AsyncSession,\n        /,\n        ids: List[int],\n        flush: bool = False,\n        commit: bool = True,\n    ) -> Sequence[User]:\n        users = await self._update_all(\n            __session__,\n            model=User,\n            values={\n                User.is_active.key: False,\n            },\n            filters={\n                User.id: {\n                    Operators.IN: ids,\n                },\n            },\n            flush=flush,\n            commit=commit,\n        )\n\n        return users\n\n    async def delete(\n        self,\n        __session__: AsyncSession,\n        /,\n        id: int,\n        flush: bool = False,\n        commit: bool = True,\n    ) -> bool:\n        is_deleted = await self._delete(\n            __session__,\n            model=User,\n            filters={\n                User.id: {\n                    Operators.EQUAL: id,\n                },\n            },\n            flush=flush,\n            commit=commit,\n        )\n\n        return is_deleted\n\n    async def delete_all(\n        self,\n        __session__: AsyncSession,\n        /,\n        ids: List[int],\n        flush: bool = False,\n        commit: bool = True,\n    ) -> bool:\n        is_deleted = await self._delete_all(\n            __session__,\n            model=User,\n            filters={\n                User.id: {\n                    Operators.IN: ids,\n                },\n            },\n            flush=flush,\n            commit=commit,\n        )\n\n        return is_deleted\n```\n\nTo create an async service, you just have to inherit your class from AsyncService.\n\n```\n# MODULES\nfrom logging import Logger\nfrom typing import List, Optional, Tuple\n\n# SQLALCHEMY\nfrom sqlalchemy.ext.asyncio import AsyncSession\n\n# PYSQL_REPO\nfrom pysql_repo.asyncio import AsyncService, with_async_session\n\n# REPOSITORIES\nfrom tests.repositories.user.async_user_repository import AsyncUserRepository\n\n# MODELS\nfrom tests.models.schemas.user import UserCreate, UserRead\n\n\nclass AsyncUserService(AsyncService[AsyncUserRepository]):\n    def __init__(\n        self,\n        user_repository: AsyncUserRepository,\n        logger: Logger,\n    ) -> None:\n        super().__init__(\n            repository=user_repository,\n        )\n        self._logger = logger\n\n    async def get_users(\n        self,\n        __session__: AsyncSession,\n        /,\n        ids_in: Optional[List[int]] = None,\n        ids_not_in: Optional[List[int]] = None,\n        emails_iin: Optional[List[str]] = None,\n        emails_in: Optional[List[str]] = None,\n        emails_not_iin: Optional[List[str]] = None,\n        emails_not_in: Optional[List[str]] = None,\n        email_ilike: Optional[str] = None,\n        email_like: Optional[str] = None,\n        email_not_ilike: Optional[str] = None,\n        email_not_like: Optional[str] = None,\n        email_equal: Optional[str] = None,\n        email_iequal: Optional[str] = None,\n        email_different: Optional[str] = None,\n        email_idifferent: Optional[str] = None,\n        zip_codes_in: Optional[List[int]] = None,\n        zip_codes_not_in: Optional[List[int]] = None,\n        is_active_equal: Optional[bool] = None,\n        load_addresses: bool = True,\n        load_city: bool = True,\n        order_by: Optional[List[str]] = None,\n        direction: Optional[List[str]] = None,\n    ) -> List[UserRead]:\n        users = await self._repository.get_all(\n            __session__,\n            ids_in=ids_in,\n            ids_not_in=ids_not_in,\n            emails_iin=emails_iin,\n            emails_in=emails_in,\n            emails_not_iin=emails_not_iin,\n            emails_not_in=emails_not_in,\n            email_ilike=email_ilike,\n            email_like=email_like,\n            email_not_ilike=email_not_ilike,\n            email_not_like=email_not_like,\n            email_equal=email_equal,\n            email_iequal=email_iequal,\n            email_different=email_different,\n            email_idifferent=email_idifferent,\n            zip_codes_in=zip_codes_in,\n            zip_codes_not_in=zip_codes_not_in,\n            is_active_equal=is_active_equal,\n            load_addresses=load_addresses,\n            load_city=load_city,\n            order_by=order_by,\n            direction=direction,\n        )\n\n        return [UserRead.model_validate(item) for item in users]\n\n    async def get_users_paginate(\n        self,\n        __session__: AsyncSession,\n        /,\n        page: int,\n        per_page: int,\n        ids_in: Optional[List[int]] = None,\n        ids_not_in: Optional[List[int]] = None,\n        emails_iin: Optional[List[str]] = None,\n        emails_in: Optional[List[str]] = None,\n        emails_not_iin: Optional[List[str]] = None,\n        emails_not_in: Optional[List[str]] = None,\n        email_ilike: Optional[str] = None,\n        email_like: Optional[str] = None,\n        email_not_ilike: Optional[str] = None,\n        email_not_like: Optional[str] = None,\n        email_equal: Optional[str] = None,\n        email_iequal: Optional[str] = None,\n        email_different: Optional[str] = None,\n        email_idifferent: Optional[str] = None,\n        zip_codes_in: Optional[List[int]] = None,\n        zip_codes_not_in: Optional[List[int]] = None,\n        is_active_equal: Optional[bool] = None,\n        load_addresses: bool = True,\n        load_city: bool = True,\n        order_by: Optional[List[str]] = None,\n        direction: Optional[List[str]] = None,\n    ) -> Tuple[List[UserRead], str]:\n        users, pagination = await self._repository.get_paginate(\n            __session__,\n            page=page,\n            per_page=per_page,\n            ids_in=ids_in,\n            ids_not_in=ids_not_in,\n            emails_iin=emails_iin,\n            emails_in=emails_in,\n            emails_not_iin=emails_not_iin,\n            emails_not_in=emails_not_in,\n            email_ilike=email_ilike,\n            email_like=email_like,\n            email_not_ilike=email_not_ilike,\n            email_not_like=email_not_like,\n            email_equal=email_equal,\n            email_iequal=email_iequal,\n            email_different=email_different,\n            email_idifferent=email_idifferent,\n            zip_codes_in=zip_codes_in,\n            zip_codes_not_in=zip_codes_not_in,\n            is_active_equal=is_active_equal,\n            load_addresses=load_addresses,\n            load_city=load_city,\n            order_by=order_by,\n            direction=direction,\n        )\n\n        return [UserRead.model_validate(item) for item in users], pagination\n\n    async def get_user_by_id(\n        self,\n        __session__: AsyncSession,\n        /,\n        id: int,\n    ) -> Optional[UserRead]:\n        user = await self._repository.get_by_id(\n            __session__,\n            id=id,\n        )\n\n        if user is None:\n            return None\n\n        return UserRead.model_validate(user)\n\n    async def create_user(\n        self,\n        __session__: AsyncSession,\n        /,\n        data: UserCreate,\n    ) -> UserRead:\n        user = await self._repository.create(\n            __session__,\n            data=data,\n            flush=True,\n        )\n\n        return UserRead.model_validate(user)\n\n    async def create_users(\n        self,\n        __session__: AsyncSession,\n        /,\n        data: List[UserCreate],\n    ) -> List[UserRead]:\n        users = await self._repository.create_all(\n            __session__,\n            data=data,\n            flush=True,\n        )\n\n        return [UserRead.model_validate(user) for user in users]\n\n    async def patch_email(\n        self,\n        __session__: AsyncSession,\n        /,\n        id: int,\n        email: str,\n    ) -> UserRead:\n        user = await self._repository.patch_email(\n            __session__,\n            id=id,\n            email=email,\n            flush=True,\n        )\n\n        return UserRead.model_validate(user)\n\n    async def bulk_patch_email(\n        self,\n        __session__: AsyncSession,\n        /,\n        data: List[Tuple[int, str]],\n    ) -> List[UserRead]:\n        users = await self._repository.bulk_patch_email(\n            __session__,\n            data=data,\n            flush=True,\n        )\n\n        return [UserRead.model_validate(user) for user in users]\n\n    async def patch_disable(\n        self,\n        __session__: AsyncSession,\n        /,\n        ids: List[int],\n    ) -> List[UserRead]:\n        users = await self._repository.patch_disable(\n            __session__,\n            ids=ids,\n            flush=True,\n        )\n\n        return [UserRead.model_validate(user) for user in users]\n\n    async def delete_by_id(\n        self,\n        __session__: AsyncSession,\n        /,\n        id: int,\n    ) -> bool:\n        return await self._repository.delete(\n            __session__,\n            id=id,\n            flush=True,\n        )\n\n    async def delete_by_ids(\n        self,\n        __session__: AsyncSession,\n        /,\n        ids: List[int],\n    ) -> bool:\n        return await self._repository.delete_all(\n            __session__,\n            ids=ids,\n            flush=True,\n        )\n\n```\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "A project to have a base repository class to perform select/insert/update/delete with dynamic syntax",
    "version": "0.7.4.0",
    "project_urls": {
        "Download": "https://github.com/Impro02/pysql-repo/archive/refs/tags/0.7.4.0.tar.gz",
        "Homepage": "https://github.com/Impro02/pysql-repo"
    },
    "split_keywords": [],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "54c1318eca0019bb831a75948c7881adea9b2c28f1e57aaecfbbfbd7e8e7aabf",
                "md5": "0036db14248d3d4ed51696ad5f83fab5",
                "sha256": "e54e86fd34df1e44c7a0ad0c7106034b9e731606d4b7fb93656f790bb5f9ecba"
            },
            "downloads": -1,
            "filename": "pysql_repo-0.7.4.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "0036db14248d3d4ed51696ad5f83fab5",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.8",
            "size": 27053,
            "upload_time": "2024-07-16T09:38:59",
            "upload_time_iso_8601": "2024-07-16T09:38:59.080799Z",
            "url": "https://files.pythonhosted.org/packages/54/c1/318eca0019bb831a75948c7881adea9b2c28f1e57aaecfbbfbd7e8e7aabf/pysql_repo-0.7.4.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "4819bacf94b17a2352cf8dd736da1b6e6ff1170aa584787031380bf816a8ca28",
                "md5": "016bc660898e16b93728103fcd806857",
                "sha256": "4e9a59780d67eddb4d61bf077d7faba8b5e29d0c6316a0839c9b3e42b6a2c526"
            },
            "downloads": -1,
            "filename": "pysql-repo-0.7.4.0.tar.gz",
            "has_sig": false,
            "md5_digest": "016bc660898e16b93728103fcd806857",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.8",
            "size": 28245,
            "upload_time": "2024-07-16T09:39:00",
            "upload_time_iso_8601": "2024-07-16T09:39:00.885115Z",
            "url": "https://files.pythonhosted.org/packages/48/19/bacf94b17a2352cf8dd736da1b6e6ff1170aa584787031380bf816a8ca28/pysql-repo-0.7.4.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-07-16 09:39:00",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "Impro02",
    "github_project": "pysql-repo",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "requirements": [],
    "lcname": "pysql-repo"
}
        
Elapsed time: 0.97032s