Aller au contenu principal

Migrations du schéma (Alembic)

Alembic est maître du schéma, y compris les hypertables TimescaleDB, la compression et les agrégats continus. La chaîne est linéaire, avec une seule tête.

Historique des migrations​

RévisionFichierModifications
001001_initial_schema.pySchéma initial : assets (index unique sur l'ISIN), asset_listings, asset_mappings, prices_eod, fundamentals, usage_logs, et les anciennes tables stock_data, data_requests, cache_status
002002_refonte_fundamentals.pyfundamentals_highlights, financial_statements, earnings_history, analyst_ratings, etf_details, etf_holdings
003003_index_constituents.pyTable index_constituents (non utilisée par le code)
004004_fix_assets_columns.pyColonnes de profil de assets
005005_premium_fields.pyColonnes de positions vendeuses, TTM et croissance ; colonnes GICS ; earnings_trend, esg_scores, outstanding_shares_history
006006_prices_eod_resolution.pyresolution, adjusted, source sur prices_eod ; ingest_log
007007_realtime_tables.pyHypertable prices_intraday (rétention de 30 jours), realtime_subscriptions
008008_drop_legacy_tables.pyDestructive : supprime les anciennes tables de prix
009009_fix_assets_isin_unique.pyFusionne les doublons d'ISIN, index unique sur l'ISIN et contrainte d'identité des cotations
010010_news_articles.pynews_articles (url unique)
011011_provider_health.pyHypertable provider_health_log, provider_health_daily, provider_alerts
012012_alembic_schema_authority.pyAlembic prend en charge les hypertables, la compression et les agrégats hebdomadaires/mensuels
013013_solvency_ratios.pyRatios de solvabilité et coût de la dette ; macro_rates_cache
014014_prices_per_listing.pyprices_eod reconstruite par cotation : clé (asset_listing_id, resolution, time), lignes redatées à leur séance ; compression et agrégats par cotation
015015_dividend_yield_as_ratio.pyRendements du dividende enregistrés convertis de pourcentages en ratios
016016_price_series_adjustments.pyprice_series_adjustments : comment chaque série de prix enregistrée est ajustée et quand elle a été récupérée d'un seul tenant pour la dernière fois. Les séries enregistrées avant sont récupérées de nouveau en entier à leur prochaine ingestion

Exécution des migrations​

  1. Le conteneur de l'API exécute alembic upgrade head dans entrypoint.sh avant de démarrer l'application. Le service fonrex-migrate (profil migrate) fait la même chose seul.
  2. main.py compare la révision enregistrée dans alembic_version avec la tête. Une base en retard sur le code est marquée indisponible et les routes qui en ont besoin répondent 503 : l'application ne modifie jamais le schéma elle-même.

La migration 014 supprime d'abord les jobs TimescaleDB des tables de prix (en attendant la fin de celui qui tourne) et verrouille prices_eod : sinon, un job de compression ou de rafraîchissement exécuté en même temps provoquerait un interblocage. La migration recrée ensuite les jobs.

Ajouter une migration​

alembic revision -m "describe_the_change"

Renommez le nouveau fichier de alembic/versions/ et placez ses identifiants après la dernière migration (revision = "017", down_revision = "016", fichier 017_describe_the_change.py), puis :

alembic upgrade head
make migration-check # one head only
  • Ajoutez la migration au tableau des migrations de ARCHITECTURE.md (tests/test_docs_consistency.py).
  • Une migration qui déplace ou réécrit des données s'accompagne d'un test dans tests/test_timescale_integration.py, exécuté sur un vrai TimescaleDB (make test-db).
  • Écrivez aussi downgrade() : les tests d'intégration redescendent puis remontent.