fix: serialize schema init for postgres
This commit is contained in:
@@ -1,11 +1,15 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from sqlalchemy import create_engine
|
||||
from sqlalchemy.orm import Session, sessionmaker
|
||||
from sqlalchemy import create_engine, text
|
||||
from sqlalchemy.engine import URL, make_url
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
|
||||
from packages.adapters.sqlalchemy_impl.models import Base
|
||||
|
||||
|
||||
SCHEMA_INIT_LOCK_ID = 2026061501
|
||||
|
||||
|
||||
def build_engine(
|
||||
database_url: str,
|
||||
*,
|
||||
@@ -42,5 +46,33 @@ def build_session_factory(
|
||||
return engine, session_factory
|
||||
|
||||
|
||||
def _build_admin_url(database_url: str) -> URL:
|
||||
url = make_url(database_url)
|
||||
return url.set(database="postgres")
|
||||
|
||||
|
||||
def ensure_database_exists(database_url: str) -> None:
|
||||
target_url = make_url(database_url)
|
||||
admin_engine = create_engine(_build_admin_url(database_url), isolation_level="AUTOCOMMIT")
|
||||
try:
|
||||
with admin_engine.connect() as connection:
|
||||
exists = connection.execute(
|
||||
text("SELECT 1 FROM pg_database WHERE datname = :database_name"),
|
||||
{"database_name": target_url.database},
|
||||
).scalar()
|
||||
if exists:
|
||||
return
|
||||
connection.execute(text(f'CREATE DATABASE "{target_url.database}"'))
|
||||
finally:
|
||||
admin_engine.dispose()
|
||||
|
||||
|
||||
def initialize_database(engine) -> None:
|
||||
Base.metadata.create_all(bind=engine)
|
||||
with engine.connect() as connection:
|
||||
connection.execute(text("SELECT pg_advisory_lock(:lock_id)"), {"lock_id": SCHEMA_INIT_LOCK_ID})
|
||||
try:
|
||||
Base.metadata.create_all(bind=connection)
|
||||
connection.commit()
|
||||
finally:
|
||||
connection.execute(text("SELECT pg_advisory_unlock(:lock_id)"), {"lock_id": SCHEMA_INIT_LOCK_ID})
|
||||
connection.commit()
|
||||
|
||||
Reference in New Issue
Block a user