Jun 26 MT-0 phase
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
"""
|
||||
control/base.py
|
||||
---------------
|
||||
Standalone SQLAlchemy foundation for the control plane.
|
||||
|
||||
`ControlBase` keeps control-plane table metadata fully separate from the
|
||||
tenant-schema models declared on `app.db.Model`. The engine is built lazily
|
||||
from the `CONTROL_DATABASE_URL` environment variable.
|
||||
"""
|
||||
|
||||
import os
|
||||
from contextlib import contextmanager
|
||||
|
||||
from sqlalchemy import create_engine
|
||||
from sqlalchemy.orm import declarative_base, sessionmaker
|
||||
|
||||
# Every control model subclasses this base — its own metadata collection.
|
||||
ControlBase = declarative_base()
|
||||
|
||||
|
||||
def get_control_database_url() -> str:
|
||||
"""Return CONTROL_DATABASE_URL or raise a clear error if unset."""
|
||||
url = os.environ.get('CONTROL_DATABASE_URL')
|
||||
if not url:
|
||||
raise RuntimeError(
|
||||
"CONTROL_DATABASE_URL is not set. Example: "
|
||||
"mysql+pymysql://jqc_control:password@localhost/jqc_control"
|
||||
)
|
||||
return url
|
||||
|
||||
|
||||
_engine = None
|
||||
_Session = None
|
||||
|
||||
|
||||
def get_engine():
|
||||
"""Lazily build (and cache) the control-plane engine."""
|
||||
global _engine
|
||||
if _engine is None:
|
||||
_engine = create_engine(
|
||||
get_control_database_url(),
|
||||
pool_pre_ping=True,
|
||||
pool_recycle=1800,
|
||||
future=True,
|
||||
)
|
||||
return _engine
|
||||
|
||||
|
||||
def get_sessionmaker():
|
||||
"""Lazily build (and cache) the control-plane sessionmaker."""
|
||||
global _Session
|
||||
if _Session is None:
|
||||
_Session = sessionmaker(
|
||||
bind=get_engine(), future=True, expire_on_commit=False
|
||||
)
|
||||
return _Session
|
||||
|
||||
|
||||
@contextmanager
|
||||
def control_session():
|
||||
"""Context-managed session — commits on success, rolls back on error.
|
||||
|
||||
Usage:
|
||||
with control_session() as s:
|
||||
s.add(obj)
|
||||
"""
|
||||
session = get_sessionmaker()()
|
||||
try:
|
||||
yield session
|
||||
session.commit()
|
||||
except Exception:
|
||||
session.rollback()
|
||||
raise
|
||||
finally:
|
||||
session.close()
|
||||
Reference in New Issue
Block a user