Files
decision/backend/alembic/env.py
Yvv 25437f24e3 Sprint 1 : scaffolding complet de Glibredecision
Plateforme de decisions collectives pour Duniter/G1.
Backend FastAPI async + PostgreSQL (14 tables, 8 routers, 6 services,
moteur de vote avec formule d'inertie WoT/Smith/TechComm).
Frontend Nuxt 4 + Nuxt UI v3 + Pinia (9 pages, 5 stores).
Infrastructure Docker + Woodpecker CI + Traefik.
Documentation technique et utilisateur (15 fichiers).
Seed : Licence G1, Engagement Forgeron v2.0.0, 4 protocoles de vote.
30 tests unitaires (formules, mode params, vote nuance) -- tous verts.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 12:46:11 +01:00

110 lines
2.7 KiB
Python

"""Alembic async environment for Glibredecision.
Uses asyncpg via SQLAlchemy's async engine.
All models are imported so that Base.metadata is fully populated
before autogenerate runs.
"""
from __future__ import annotations
import asyncio
from logging.config import fileConfig
from sqlalchemy import pool
from sqlalchemy.engine import Connection
from sqlalchemy.ext.asyncio import async_engine_from_config
from alembic import context
# Import settings to get the DATABASE_URL
from app.config import settings
# Import Base for target_metadata
from app.database import Base
# Import ALL models so their tables are registered on Base.metadata
from app.models import ( # noqa: F401
DuniterIdentity,
Session,
Document,
DocumentItem,
ItemVersion,
Decision,
DecisionStep,
VoteSession,
Vote,
Mandate,
MandateStep,
VotingProtocol,
FormulaConfig,
SanctuaryEntry,
BlockchainCache,
)
# Alembic Config object
config = context.config
# Interpret the config file for Python logging
if config.config_file_name is not None:
fileConfig(config.config_file_name)
# Override sqlalchemy.url with the real DATABASE_URL from settings
config.set_main_option("sqlalchemy.url", settings.DATABASE_URL)
# Target metadata for autogenerate support
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() 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: Connection) -> None:
"""Run migrations with an active 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 with 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()