env.py 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. from __future__ import annotations
  2. import os
  3. from logging.config import fileConfig
  4. from alembic import context
  5. from sqlalchemy import engine_from_config, pool
  6. config = context.config
  7. if config.config_file_name is not None:
  8. fileConfig(config.config_file_name)
  9. database_url = os.environ.get("SQLALCHEMY_DATABASE_URI") or os.environ.get(
  10. "DATABASE_URL"
  11. )
  12. if not database_url:
  13. raise RuntimeError(
  14. "SQLALCHEMY_DATABASE_URI or DATABASE_URL must be configured for migrations"
  15. )
  16. # ConfigParser treats percent signs as interpolation markers.
  17. config.set_main_option("sqlalchemy.url", database_url.replace("%", "%%"))
  18. target_metadata = None
  19. MIGRATION_ADVISORY_LOCK_ID = 2026072201
  20. def run_migrations_offline() -> None:
  21. context.configure(
  22. url=database_url,
  23. target_metadata=target_metadata,
  24. literal_binds=True,
  25. dialect_opts={"paramstyle": "named"},
  26. )
  27. with context.begin_transaction():
  28. context.run_migrations()
  29. def run_migrations_online() -> None:
  30. connectable = engine_from_config(
  31. config.get_section(config.config_ini_section, {}),
  32. prefix="sqlalchemy.",
  33. poolclass=pool.NullPool,
  34. )
  35. with connectable.connect() as connection:
  36. connection.exec_driver_sql(
  37. "SELECT pg_advisory_lock(%s)", (MIGRATION_ADVISORY_LOCK_ID,)
  38. )
  39. connection.commit()
  40. try:
  41. context.configure(connection=connection, target_metadata=target_metadata)
  42. with context.begin_transaction():
  43. context.run_migrations()
  44. finally:
  45. connection.exec_driver_sql(
  46. "SELECT pg_advisory_unlock(%s)", (MIGRATION_ADVISORY_LOCK_ID,)
  47. )
  48. connection.commit()
  49. if context.is_offline_mode():
  50. run_migrations_offline()
  51. else:
  52. run_migrations_online()