spakky-sqlalchemy¶
SQLAlchemy 통합 - ORM, Repository, Transaction, Outbox Contribution
spakky-sqlalchemy는 spakky-data의 Repository/Transaction 계약을 SQLAlchemy engine과
session으로 구현하는 플러그인입니다. 처음 사용하는 경우에는
데이터베이스 가이드에서 도메인 Aggregate, ORM table,
Repository, @Transactional() UseCase를 한 흐름으로 확인하세요.
Outbox storage/table은 base plugin 본체가 아니라
spakky.contributions.spakky.outbox contribution으로 등록됩니다. load_plugins(include=...)
사용 시 spakky-outbox와 spakky-sqlalchemy가 모두 include set에 있어야 이
contribution이 로드됩니다. 설치 시에는 spakky-outbox를 별도로 추가하거나
spakky-sqlalchemy[outbox] extra를 사용하세요.
Agent state/signal/evidence persistence도 base plugin 본체가 아니라
spakky.contributions.spakky.agent contribution으로 등록됩니다. Durable @Agent
execution을 운영에서 사용하려면 spakky-agent와 spakky-sqlalchemy[agent]를
함께 설치하고 두 plugin을 모두 active 상태로 로드해야 합니다. 이 contribution은
SqlAlchemyAgentStateRepository, SqlAlchemyAgentSignalRepository,
SqlAlchemyAgentEvidenceRepository와 AgentStateTable, AgentSignalTable,
AgentEvidenceTable을 등록합니다. 운영용 in-memory fallback은 제공하지 않습니다.
메인¶
spakky.plugins.sqlalchemy.main
¶
initialize(app)
¶
Initialize the SQLAlchemy plugin.
Registers SQLAlchemy configuration, schema registry, session managers, and transaction handlers. Async Pods are only registered when support_async_mode is True in the configuration.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
app
|
SpakkyApplication
|
The Spakky application instance. |
required |
Source code in plugins/spakky-sqlalchemy/src/spakky/plugins/sqlalchemy/main.py
options: show_root_heading: false
설정¶
spakky.plugins.sqlalchemy.common.config
¶
SQLAlchemyConnectionConfig()
¶
Bases: BaseSettings
Source code in plugins/spakky-sqlalchemy/src/spakky/plugins/sqlalchemy/common/config.py
connection_string
instance-attribute
¶
SQLAlchemy database connection URL (e.g. postgresql+psycopg://user:pass@host/db).
echo = False
class-attribute
instance-attribute
¶
If True, the engine logs all SQL statements to the default logger.
echo_pool = False
class-attribute
instance-attribute
¶
If True, the connection pool logs all checkout/checkin events.
DEFAULT_POOL_SIZE = 5
class-attribute
¶
Default number of connections in the pool.
DEFAULT_POOL_MAX_OVERFLOW = 10
class-attribute
¶
Default maximum overflow connections.
DEFAULT_POOL_TIMEOUT = 30.0
class-attribute
¶
Default seconds to wait when pool is exhausted.
DEFAULT_POOL_RECYCLE = -1
class-attribute
¶
Default connection recycle time (-1 = disabled).
DEFAULT_POOL_PRE_PING = False
class-attribute
¶
Default pre-ping setting.
pool_size = DEFAULT_POOL_SIZE
class-attribute
instance-attribute
¶
Number of connections to maintain persistently in the pool.
pool_max_overflow = DEFAULT_POOL_MAX_OVERFLOW
class-attribute
instance-attribute
¶
Maximum number of connections that can be opened beyond pool_size.
pool_timeout = DEFAULT_POOL_TIMEOUT
class-attribute
instance-attribute
¶
Seconds to wait before raising an error when the pool is exhausted.
pool_recycle = DEFAULT_POOL_RECYCLE
class-attribute
instance-attribute
¶
Recycle connections after this many seconds to prevent stale connections. Recommended when connecting through a proxy or firewall with idle timeouts.
pool_pre_ping = DEFAULT_POOL_PRE_PING
class-attribute
instance-attribute
¶
If True, tests each connection for liveness before returning it from the pool. Prevents errors caused by connections dropped by the database server.
session_autoflush = True
class-attribute
instance-attribute
¶
If True, the session automatically flushes pending changes before queries.
session_expire_on_commit = True
class-attribute
instance-attribute
¶
If True, ORM objects are expired after each commit, forcing a reload on next access.
autocommit = True
class-attribute
instance-attribute
¶
If True, transactions are automatically committed after with statements. If False, transactions must be manually committed or rolled back.
support_async_mode = True
class-attribute
instance-attribute
¶
If True, registers async Pods (AsyncSessionManager, AsyncTransaction). Set to False when using database drivers that don't support async operations.
options: show_root_heading: false
ORM¶
spakky.plugins.sqlalchemy.orm.table
¶
AbstractTable
¶
Bases: DeclarativeBase, AsyncAttrs
Base table class for SQLAlchemy ORM integration with Spakky.
Use this class for infrastructure tables that don't map to domain models (e.g., outbox tables, audit logs). For tables that map to domain entities, use AbstractMappableTable instead.
AbstractMappableTable
¶
Bases: AbstractTable
Table class with domain object mapping support.
Use this class for tables that map to domain entities. Subclasses must implement from_domain() and to_domain() methods for bidirectional mapping.
options: show_root_heading: false
spakky.plugins.sqlalchemy.orm.schema_registry
¶
SchemaRegistry()
¶
Bases: ITagRegistryAware
Registry that maps domain types to SQLAlchemy table schemas.
Source code in plugins/spakky-sqlalchemy/src/spakky/plugins/sqlalchemy/orm/schema_registry.py
metadata
property
¶
Return MetaData containing only tables registered via @Table tag.
This filters out tables that were defined but not scanned by the SpakkyApplication, ensuring only application-scoped tables are included.
Returns:
| Type | Description |
|---|---|
MetaData
|
MetaData with only @Table-tagged tables. |
get_type(domain_type)
¶
Look up the table class registered for the given domain type.
Source code in plugins/spakky-sqlalchemy/src/spakky/plugins/sqlalchemy/orm/schema_registry.py
from_domain(aggregate)
¶
Convert a domain object to its corresponding table instance.
Source code in plugins/spakky-sqlalchemy/src/spakky/plugins/sqlalchemy/orm/schema_registry.py
options: show_root_heading: false
options: show_root_heading: false
영속성¶
spakky.plugins.sqlalchemy.persistency.repository
¶
CannotDetermineAggregateTypeError
¶
Bases: AbstractSpakkySqlAlchemyPersistencyError
Raised when aggregate type cannot be resolved from generic parameters.
AbstractGenericRepository(session_manager, schema_registry, aggregate_collector)
¶
Bases: IGenericRepository[AggregateRootT, AggregateIdT], ABC
Generic repository implementation for SQLAlchemy.
This class provides basic CRUD operations using SQLAlchemy sessions. It serves as a base class for specific entity repositories.
Resolve aggregate type from generic parameters and store dependencies.
Source code in plugins/spakky-sqlalchemy/src/spakky/plugins/sqlalchemy/persistency/repository.py
AbstractAsyncGenericRepository(session_manager, schema_registry, aggregate_collector)
¶
Bases: IAsyncGenericRepository[AggregateRootT, AggregateIdT], ABC
Async generic repository implementation for SQLAlchemy.
This class provides basic CRUD operations using SQLAlchemy's async sessions. It serves as a base class for specific entity repositories that require async support.
Resolve aggregate type from generic parameters and store dependencies.
Source code in plugins/spakky-sqlalchemy/src/spakky/plugins/sqlalchemy/persistency/repository.py
options: show_root_heading: false
spakky.plugins.sqlalchemy.persistency.transaction
¶
Transaction(config, session_manager)
¶
Bases: AbstractTransaction
SQLAlchemy synchronous transaction implementation.
Initialize with autocommit config and session manager.
Source code in plugins/spakky-sqlalchemy/src/spakky/plugins/sqlalchemy/persistency/transaction.py
AsyncTransaction(config, session_manager)
¶
Bases: AbstractAsyncTransaction
SQLAlchemy asynchronous transaction implementation.
Initialize with autocommit config and async session manager.
Source code in plugins/spakky-sqlalchemy/src/spakky/plugins/sqlalchemy/persistency/transaction.py
options: show_root_heading: false
spakky.plugins.sqlalchemy.persistency.session_manager
¶
SessionNotInitializedError
¶
Bases: AbstractSpakkySqlAlchemyPersistencyError
Raised when trying to access a session that has not been initialized.
SessionManager(connection_manager)
¶
Bases: IApplicationContextAware
Manages scoped synchronous SQLAlchemy sessions.
Initialize with engine from connection manager.
Source code in plugins/spakky-sqlalchemy/src/spakky/plugins/sqlalchemy/persistency/session_manager.py
AsyncSessionManager(connection_manager)
¶
Bases: IApplicationContextAware
Manages scoped asynchronous SQLAlchemy sessions.
Initialize with engine from async connection manager.
Source code in plugins/spakky-sqlalchemy/src/spakky/plugins/sqlalchemy/persistency/session_manager.py
options: show_root_heading: false
spakky.plugins.sqlalchemy.persistency.connection_manager
¶
Connection managers for SQLAlchemy engines.
This module provides connection managers that handle SQLAlchemy engine lifecycle, including proper disposal on application shutdown.
ConnectionManager(config)
¶
Manages synchronous SQLAlchemy engine lifecycle.
Create a synchronous SQLAlchemy engine from configuration.
Source code in plugins/spakky-sqlalchemy/src/spakky/plugins/sqlalchemy/persistency/connection_manager.py
connection
property
¶
Get the SQLAlchemy Engine instance.
AsyncConnectionManager(config)
¶
Manages asynchronous SQLAlchemy engine lifecycle.
Note: Does not implement IAsyncService because AsyncEngine.dispose() must be called from the same event loop where connections were created. In test environments with pytest-asyncio, this means dispose must be called from the test's event loop, not ApplicationContext's internal event loop thread.
Create an asynchronous SQLAlchemy engine from configuration.
Source code in plugins/spakky-sqlalchemy/src/spakky/plugins/sqlalchemy/persistency/connection_manager.py
options: show_root_heading: false
options: show_root_heading: false
Outbox¶
spakky.plugins.sqlalchemy.contributions.outbox
¶
SQLAlchemy contribution for the spakky-outbox feature.
initialize(app)
¶
Register SQLAlchemy-backed Outbox infrastructure.
Source code in plugins/spakky-sqlalchemy/src/spakky/plugins/sqlalchemy/contributions/outbox.py
options: show_root_heading: false
spakky.plugins.sqlalchemy.outbox.storage
¶
SQLAlchemy implementation of IOutboxStorage / IAsyncOutboxStorage.
SqlAlchemyOutboxStorage(session_manager, connection_manager, config=None)
¶
Bases: IOutboxStorage
Synchronous SQLAlchemy-based Outbox storage implementation.
- save(): uses the current transactional session (same TX as business data).
- fetch_pending/mark_published/increment_retry: use independent sessions.
Source code in plugins/spakky-sqlalchemy/src/spakky/plugins/sqlalchemy/outbox/storage.py
AsyncSqlAlchemyOutboxStorage(session_manager, connection_manager, config=None)
¶
Bases: IAsyncOutboxStorage
Asynchronous SQLAlchemy-based Outbox storage implementation.
- save(): uses the current transactional session (same TX as business data).
- fetch_pending/mark_published/increment_retry: use independent sessions.
Source code in plugins/spakky-sqlalchemy/src/spakky/plugins/sqlalchemy/outbox/storage.py
options: show_root_heading: false
spakky.plugins.sqlalchemy.outbox.table
¶
SQLAlchemy table definition for the Outbox pattern.
OutboxMessageTable
¶
Bases: AbstractTable
Outbox message table for transactional outbox pattern.
This is an infrastructure table that doesn't map to a domain model, so it inherits from AbstractTable (not AbstractMappableTable).
options: show_root_heading: false
Agent Persistence¶
spakky.plugins.sqlalchemy.contributions.agent
¶
SQLAlchemy contribution for the spakky-agent feature.
initialize(app)
¶
Register SQLAlchemy-backed agent persistence infrastructure.
Source code in plugins/spakky-sqlalchemy/src/spakky/plugins/sqlalchemy/contributions/agent.py
options: show_root_heading: false
spakky.plugins.sqlalchemy.agent.repository
¶
SQLAlchemy repository implementations for spakky-agent contracts.
SqlAlchemyAgentStateRepository(session_manager)
¶
Bases: IAgentStateRepository
SQLAlchemy materialized state repository for agent executions.
Source code in plugins/spakky-sqlalchemy/src/spakky/plugins/sqlalchemy/agent/repository.py
SqlAlchemyAgentSignalRepository(session_manager)
¶
Bases: IAgentSignalRepository
SQLAlchemy durable inbound queue repository for agent signals.
Source code in plugins/spakky-sqlalchemy/src/spakky/plugins/sqlalchemy/agent/repository.py
SqlAlchemyAgentEvidenceRepository(session_manager)
¶
Bases: IAgentEvidenceRepository
SQLAlchemy append-only repository for agent evidence artifacts.
Source code in plugins/spakky-sqlalchemy/src/spakky/plugins/sqlalchemy/agent/repository.py
options: show_root_heading: false
spakky.plugins.sqlalchemy.agent.table
¶
SQLAlchemy schema mappings for spakky-agent persistence contracts.
AgentStateTable
¶
AgentSignalTable
¶
AgentEvidenceTable
¶
Bases: AbstractMappableTable[AgentEvidence]
Append-only evidence table for agent execution artifacts.
options: show_root_heading: false
에러¶
options: show_root_heading: false
추가 모듈¶
Errors for SQLAlchemy-backed agent persistence.
AgentPersistenceRowNotFoundError
¶
Bases: AbstractSpakkySqlAlchemyPersistencyError
Raised when an agent persistence row cannot be found.