Skip to main content

Spakky Data

Spakky Framework를 위한 데이터 접근 레이어 추상화입니다. Repository와 transaction boundary를 application layer에서 backend-neutral하게 선언하도록 돕습니다.

설치

pip install spakky-data

주요 기능

  • Repository 패턴: Aggregate 영속화를 위한 generic repository 인터페이스
  • 트랜잭션 관리: autocommit을 지원하는 추상 transaction 클래스
  • External Proxy: 데이터베이스가 아닌 외부 service/storage 데이터 접근용 proxy 패턴

spakky-data는 core 추상화 패키지입니다. SQLAlchemy engine/session/table mapping 구현체가 필요하면 spakky-sqlalchemy를 함께 설치하세요.

설계 원칙

Repository는 영속화 전용

Repository는 domain aggregate에 대한 CRUD operation만 처리합니다. find_by_xxx, search_xxx 같은 query method를 repository에 추가하지 마세요.

복잡한 query는 ORM/SQL을 사용해 QueryUseCase에서 직접 구현해야 합니다. Query 관심사를 도메인 레이어 밖에 두어 도메인 오염을 방지합니다.

# ❌ 잘못된 예: repository에 query 관심사 포함
class IUserRepository:
    def find_by_email(self, email: str) -> User | None: ...

# ✅ 올바른 예: QueryUseCase에서 직접 구현
@UseCase()
class FindUserByEmailUseCase(IAsyncQueryUseCase[FindUserByEmailQuery, UserDTO]):
    async def run(self, query: FindUserByEmailQuery) -> UserDTO:
        # ORM/SQL 직접 사용
        ...

외부 연동 Proxy와 Repository

관점 Repository External Proxy
목적 Domain aggregate persistence 외부 service data access
대상 Database(ORM 경유) REST API, gRPC, legacy system
연산 CRUD(save, delete, get) Read-only(get, range)
도메인 내부 bounded context 외부 service

빠른 시작

SQLAlchemy와 함께 쓰는 기본 흐름

사용자 애플리케이션에서 가장 흔한 구성은 spakky-data의 Repository/Transaction 계약을 spakky-sqlalchemy 구현체로 채우는 방식입니다.

pip install spakky-data spakky-sqlalchemy
export SPAKKY_SQLALCHEMY__CONNECTION_STRING="postgresql+psycopg://user:pass@localhost/app"
export SPAKKY_SQLALCHEMY__SUPPORT_ASYNC_MODE="true"

흐름은 다음 순서로 구성합니다.

  1. AbstractAggregateRoot 기반 domain aggregate를 정의합니다.
  2. spakky.plugins.sqlalchemy.orm.table.AbstractMappableTable@Table(Domain)으로 ORM table을 매핑합니다.
  3. spakky.plugins.sqlalchemy.persistency.repository.AbstractAsyncGenericRepository를 상속한 @Repository() 구현체를 등록합니다.
  4. @UseCase() 메서드에 @Transactional()을 붙이고 Repository를 호출합니다.
  5. 복잡한 조회는 Repository에 query method를 추가하지 않고 QueryUseCase에서 AsyncSessionManager 또는 SessionManager로 직접 SQLAlchemy query를 실행합니다.

전체 예제는 데이터베이스 가이드를 참고하세요.

Repository 패턴

domain aggregate용 repository interface를 정의합니다.

from abc import abstractmethod
from uuid import UUID

from spakky.data.persistency.repository import IAsyncGenericRepository
from spakky.domain.models.aggregate_root import AbstractAggregateRoot


class User(AbstractAggregateRoot[UUID]):
    name: str
    email: str


# Repository interface: CRUD only, query method 없음
class IUserRepository(IAsyncGenericRepository[User, UUID]):
    pass  # get, get_or_none, contains, range, save, save_all, delete, delete_all

Transaction 관리

database operation에는 추상 transaction을 사용합니다. 직접 구현해야 하는 경우도 있지만, SQLAlchemy를 쓴다면 spakky-sqlalchemyTransaction / AsyncTransaction이 이 계약을 이미 구현합니다.

from spakky.data.persistency.transaction import AbstractAsyncTransaction


class SQLAlchemyTransaction(AbstractAsyncTransaction):
    def __init__(self, session_factory, autocommit: bool = True) -> None:
        super().__init__(autocommit)
        self.session_factory = session_factory
        self.session = None

    async def initialize(self) -> None:
        self.session = self.session_factory()

    async def dispose(self) -> None:
        await self.session.close()

    async def commit(self) -> None:
        await self.session.commit()

    async def rollback(self) -> None:
        await self.session.rollback()

context manager로 사용할 수 있습니다.

async with transaction:
    user = await repository.get(user_id)
    user.name = "New Name"
    await repository.save(user)
    # 성공 시 자동 commit, exception 발생 시 rollback

외부 연동 Proxy 패턴

Proxy 인터페이스로 데이터베이스가 아닌 외부 서비스에 접근합니다. REST API, gRPC 서비스, legacy 시스템 등에 사용합니다.

from spakky.data.external.proxy import ProxyModel, IAsyncGenericProxy


# 외부 payment service의 data model
class PaymentInfo(ProxyModel[str]):
    transaction_id: str
    amount: int
    status: str


# 외부 payment service용 proxy interface
class IPaymentProxy(IAsyncGenericProxy[PaymentInfo, str]):
    pass


# 구현체는 외부 API 호출
class PaymentServiceProxy(IPaymentProxy):
    async def get(self, proxy_id: str) -> PaymentInfo:
        response = await self._http_client.get(f"/payments/{proxy_id}")
        return PaymentInfo(...)

API 레퍼런스

영속성

클래스 설명
IGenericRepository 동기 generic repository interface
IAsyncGenericRepository 비동기 generic repository interface
AbstractTransaction context manager를 가진 동기 transaction
AbstractAsyncTransaction context manager를 가진 비동기 transaction
EntityNotFoundError entity를 찾지 못했을 때 발생

외부 연동

클래스 설명
ProxyModel 외부 service data model 기반 클래스
IGenericProxy 동기 proxy interface
IAsyncGenericProxy 비동기 proxy interface

에러

클래스 설명
AbstractSpakkyPersistencyError persistency operation 기반 error
AbstractSpakkyExternalError 외부 service operation 기반 error

관련 패키지

패키지 설명
spakky-domain DDD building block(Entity, AggregateRoot, ValueObject)
spakky-event Event publisher/consumer interface

개발 검증

패키지 단위 검증은 해당 패키지 디렉토리에서 실행합니다.

uv run ruff format .
uv run ruff check .
uv run pyrefly check
uv run pytest

pytest는 각 패키지 pyproject.toml의 coverage 설정을 사용합니다.

라이선스

MIT License

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

spakky_data-7.0.0.tar.gz (7.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

spakky_data-7.0.0-py3-none-any.whl (12.6 kB view details)

Uploaded Python 3

File details

Details for the file spakky_data-7.0.0.tar.gz.

File metadata

  • Download URL: spakky_data-7.0.0.tar.gz
  • Upload date:
  • Size: 7.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for spakky_data-7.0.0.tar.gz
Algorithm Hash digest
SHA256 b413272701c8bc9b0f42b587e8a2a5296740d5e68d8a95a897e64b38d14c433f
MD5 73928687b5ffa97affdefe1278cfa1c8
BLAKE2b-256 e588220590a47df5952b576de684d72682fbe8c992b937b4b0852acb1cb428a6

See more details on using hashes here.

Provenance

The following attestation bundles were made for spakky_data-7.0.0.tar.gz:

Publisher: release.yml on E5presso/spakky-framework

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file spakky_data-7.0.0-py3-none-any.whl.

File metadata

  • Download URL: spakky_data-7.0.0-py3-none-any.whl
  • Upload date:
  • Size: 12.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for spakky_data-7.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 da17d799a9f1d197dae1de5fa095b635f93c4bef5e33c6d5c24bc1caad10cf40
MD5 b726e04f1af5e5cad70c2ab6e9e77d18
BLAKE2b-256 fa2e0ed7202460d0b95781279e96700b5673b3eec6072ba6e826bf09f456b354

See more details on using hashes here.

Provenance

The following attestation bundles were made for spakky_data-7.0.0-py3-none-any.whl:

Publisher: release.yml on E5presso/spakky-framework

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page