diff options
| author | TheSiahxyz <164138827+TheSiahxyz@users.noreply.github.com> | 2026-04-01 16:00:38 +0900 |
|---|---|---|
| committer | TheSiahxyz <164138827+TheSiahxyz@users.noreply.github.com> | 2026-04-01 16:02:03 +0900 |
| commit | 2b1db156c7ea7e0be543ab91813922b95eb043cb (patch) | |
| tree | fd19abb0845d96e160c68817190b33a0f6c0034d /shared/alembic/env.py | |
| parent | 33b14aaa2344b0fd95d1629627c3d135b24ae102 (diff) | |
feat: add SQLAlchemy ORM models and Alembic migration setup
Add SA 2.0 declarative models (CandleRow, SignalRow, OrderRow, TradeRow,
PositionRow, PortfolioSnapshotRow) mirroring existing asyncpg tables.
Set up Alembic with async PostgreSQL support and add migrate/migrate-down/
migrate-new Makefile targets. Update shared dependencies with sqlalchemy,
alembic, structlog, prometheus-client, pyyaml, aiohttp, and rich.
Diffstat (limited to 'shared/alembic/env.py')
| -rw-r--r-- | shared/alembic/env.py | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/shared/alembic/env.py b/shared/alembic/env.py new file mode 100644 index 0000000..14303f6 --- /dev/null +++ b/shared/alembic/env.py @@ -0,0 +1,66 @@ +"""Alembic environment configuration for async PostgreSQL migrations.""" + +import asyncio +from logging.config import fileConfig + +from alembic import context +from sqlalchemy import pool +from sqlalchemy.ext.asyncio import async_engine_from_config + +from shared.sa_models import Base + +config = context.config + +if config.config_file_name is not None: + fileConfig(config.config_file_name) + +target_metadata = Base.metadata + + +def run_migrations_offline() -> None: + """Run migrations in 'offline' mode. + + Configures the context with just a URL and not an Engine. + Calls to context.execute() here emit the given string to the script output. + """ + url = config.get_main_option("sqlalchemy.url") + context.configure( + url=url, + target_metadata=target_metadata, + literal_binds=True, + dialect_opts={"paramstyle": "named"}, + ) + + with context.begin_transaction(): + context.run_migrations() + + +def do_run_migrations(connection): + context.configure(connection=connection, target_metadata=target_metadata) + with context.begin_transaction(): + context.run_migrations() + + +async def run_async_migrations() -> None: + """Run migrations in 'online' mode using an async engine.""" + connectable = async_engine_from_config( + config.get_section(config.config_ini_section, {}), + prefix="sqlalchemy.", + poolclass=pool.NullPool, + ) + + async with connectable.connect() as connection: + await connection.run_sync(do_run_migrations) + + await connectable.dispose() + + +def run_migrations_online() -> None: + """Run migrations in 'online' mode.""" + asyncio.run(run_async_migrations()) + + +if context.is_offline_mode(): + run_migrations_offline() +else: + run_migrations_online() |
