semantics
This commit is contained in:
@@ -1,12 +1,12 @@
|
||||
# [DEF:backend.src.core.database:Module]
|
||||
# [DEF:DatabaseModule:Module]
|
||||
#
|
||||
# @COMPLEXITY: 3
|
||||
# @SEMANTICS: database, postgresql, sqlalchemy, session, persistence
|
||||
# @PURPOSE: Configures database connection and session management (PostgreSQL-first).
|
||||
# @LAYER: Core
|
||||
# @RELATION: DEPENDS_ON ->[sqlalchemy]
|
||||
# @RELATION: DEPENDS_ON ->[backend.src.models.mapping]
|
||||
# @RELATION: DEPENDS_ON ->[backend.src.core.auth.config]
|
||||
# @RELATION: [DEPENDS_ON] ->[MappingModels]
|
||||
# @RELATION: [DEPENDS_ON] ->[auth_config]
|
||||
# @RELATION: [DEPENDS_ON] ->[ConnectionConfig]
|
||||
#
|
||||
# @INVARIANT: A single engine instance is used for the entire application.
|
||||
|
||||
@@ -15,6 +15,7 @@ from sqlalchemy import create_engine, inspect, text
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
from ..models.mapping import Base
|
||||
from ..models.connection import ConnectionConfig
|
||||
|
||||
# Import models to ensure they're registered with Base
|
||||
from ..models import task as _task_models # noqa: F401
|
||||
from ..models import auth as _auth_models # noqa: F401
|
||||
@@ -60,6 +61,7 @@ TASKS_DATABASE_URL = os.getenv("TASKS_DATABASE_URL", DATABASE_URL)
|
||||
AUTH_DATABASE_URL = os.getenv("AUTH_DATABASE_URL", auth_config.AUTH_DATABASE_URL)
|
||||
# [/DEF:AUTH_DATABASE_URL:Constant]
|
||||
|
||||
|
||||
# [DEF:engine:Variable]
|
||||
# @COMPLEXITY: 1
|
||||
# @PURPOSE: SQLAlchemy engine for mappings database.
|
||||
@@ -70,6 +72,7 @@ def _build_engine(db_url: str):
|
||||
return create_engine(db_url, connect_args={"check_same_thread": False})
|
||||
return create_engine(db_url, pool_pre_ping=True)
|
||||
|
||||
|
||||
engine = _build_engine(DATABASE_URL)
|
||||
# [/DEF:engine:Variable]
|
||||
|
||||
@@ -106,11 +109,13 @@ TasksSessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=tasks_e
|
||||
AuthSessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=auth_engine)
|
||||
# [/DEF:AuthSessionLocal:Class]
|
||||
|
||||
|
||||
# [DEF:_ensure_user_dashboard_preferences_columns:Function]
|
||||
# @COMPLEXITY: 3
|
||||
# @PURPOSE: Applies additive schema upgrades for user_dashboard_preferences table.
|
||||
# @PRE: bind_engine points to application database where profile table is stored.
|
||||
# @POST: Missing columns are added without data loss.
|
||||
# @RELATION: [DEPENDS_ON] ->[engine]
|
||||
def _ensure_user_dashboard_preferences_columns(bind_engine):
|
||||
with belief_scope("_ensure_user_dashboard_preferences_columns"):
|
||||
table_name = "user_dashboard_preferences"
|
||||
@@ -170,12 +175,15 @@ def _ensure_user_dashboard_preferences_columns(bind_engine):
|
||||
"[database][EXPLORE] Profile preference additive migration failed: %s",
|
||||
migration_error,
|
||||
)
|
||||
|
||||
|
||||
# [/DEF:_ensure_user_dashboard_preferences_columns:Function]
|
||||
|
||||
|
||||
# [DEF:_ensure_user_dashboard_preferences_health_columns:Function]
|
||||
# @COMPLEXITY: 3
|
||||
# @PURPOSE: Applies additive schema upgrades for user_dashboard_preferences table (health fields).
|
||||
# @RELATION: [DEPENDS_ON] ->[engine]
|
||||
def _ensure_user_dashboard_preferences_health_columns(bind_engine):
|
||||
with belief_scope("_ensure_user_dashboard_preferences_health_columns"):
|
||||
table_name = "user_dashboard_preferences"
|
||||
@@ -214,12 +222,15 @@ def _ensure_user_dashboard_preferences_health_columns(bind_engine):
|
||||
"[database][EXPLORE] Profile health preference additive migration failed: %s",
|
||||
migration_error,
|
||||
)
|
||||
|
||||
|
||||
# [/DEF:_ensure_user_dashboard_preferences_health_columns:Function]
|
||||
|
||||
|
||||
# [DEF:_ensure_llm_validation_results_columns:Function]
|
||||
# @COMPLEXITY: 3
|
||||
# @PURPOSE: Applies additive schema upgrades for llm_validation_results table.
|
||||
# @RELATION: [DEPENDS_ON] ->[engine]
|
||||
def _ensure_llm_validation_results_columns(bind_engine):
|
||||
with belief_scope("_ensure_llm_validation_results_columns"):
|
||||
table_name = "llm_validation_results"
|
||||
@@ -254,6 +265,8 @@ def _ensure_llm_validation_results_columns(bind_engine):
|
||||
"[database][EXPLORE] ValidationRecord additive migration failed: %s",
|
||||
migration_error,
|
||||
)
|
||||
|
||||
|
||||
# [/DEF:_ensure_llm_validation_results_columns:Function]
|
||||
|
||||
|
||||
@@ -262,6 +275,7 @@ def _ensure_llm_validation_results_columns(bind_engine):
|
||||
# @PURPOSE: Applies additive schema upgrades for git_server_configs table.
|
||||
# @PRE: bind_engine points to application database.
|
||||
# @POST: Missing columns are added without data loss.
|
||||
# @RELATION: [DEPENDS_ON] ->[engine]
|
||||
def _ensure_git_server_configs_columns(bind_engine):
|
||||
with belief_scope("_ensure_git_server_configs_columns"):
|
||||
table_name = "git_server_configs"
|
||||
@@ -292,6 +306,8 @@ def _ensure_git_server_configs_columns(bind_engine):
|
||||
"[database][EXPLORE] GitServerConfig preference additive migration failed: %s",
|
||||
migration_error,
|
||||
)
|
||||
|
||||
|
||||
# [/DEF:_ensure_git_server_configs_columns:Function]
|
||||
|
||||
|
||||
@@ -300,6 +316,7 @@ def _ensure_git_server_configs_columns(bind_engine):
|
||||
# @PURPOSE: Applies additive schema upgrades for auth users table.
|
||||
# @PRE: bind_engine points to authentication database.
|
||||
# @POST: Missing columns are added without data loss.
|
||||
# @RELATION: [DEPENDS_ON] ->[auth_engine]
|
||||
def _ensure_auth_users_columns(bind_engine):
|
||||
with belief_scope("_ensure_auth_users_columns"):
|
||||
table_name = "users"
|
||||
@@ -314,9 +331,7 @@ def _ensure_auth_users_columns(bind_engine):
|
||||
|
||||
alter_statements = []
|
||||
if "full_name" not in existing_columns:
|
||||
alter_statements.append(
|
||||
"ALTER TABLE users ADD COLUMN full_name VARCHAR"
|
||||
)
|
||||
alter_statements.append("ALTER TABLE users ADD COLUMN full_name VARCHAR")
|
||||
if "is_ad_user" not in existing_columns:
|
||||
alter_statements.append(
|
||||
"ALTER TABLE users ADD COLUMN is_ad_user BOOLEAN NOT NULL DEFAULT FALSE"
|
||||
@@ -340,7 +355,13 @@ def _ensure_auth_users_columns(bind_engine):
|
||||
connection.execute(text(statement))
|
||||
logger.reason(
|
||||
"Auth users schema migration completed",
|
||||
extra={"table": table_name, "added_columns": [stmt.split(" ADD COLUMN ", 1)[1].split()[0] for stmt in alter_statements]},
|
||||
extra={
|
||||
"table": table_name,
|
||||
"added_columns": [
|
||||
stmt.split(" ADD COLUMN ", 1)[1].split()[0]
|
||||
for stmt in alter_statements
|
||||
],
|
||||
},
|
||||
)
|
||||
except Exception as migration_error:
|
||||
logger.warning(
|
||||
@@ -348,6 +369,8 @@ def _ensure_auth_users_columns(bind_engine):
|
||||
migration_error,
|
||||
)
|
||||
raise
|
||||
|
||||
|
||||
# [/DEF:_ensure_auth_users_columns:Function]
|
||||
|
||||
|
||||
@@ -356,6 +379,7 @@ def _ensure_auth_users_columns(bind_engine):
|
||||
# @PURPOSE: Ensures the external connection registry table exists in the main database.
|
||||
# @PRE: bind_engine points to the application database.
|
||||
# @POST: connection_configs table exists without dropping existing data.
|
||||
# @RELATION: [DEPENDS_ON] ->[ConnectionConfig]
|
||||
def ensure_connection_configs_table(bind_engine):
|
||||
with belief_scope("ensure_connection_configs_table"):
|
||||
try:
|
||||
@@ -366,6 +390,8 @@ def ensure_connection_configs_table(bind_engine):
|
||||
migration_error,
|
||||
)
|
||||
raise
|
||||
|
||||
|
||||
# [/DEF:ensure_connection_configs_table:Function]
|
||||
|
||||
|
||||
@@ -374,6 +400,7 @@ def ensure_connection_configs_table(bind_engine):
|
||||
# @PURPOSE: Adds missing FilterSource enum values to the PostgreSQL native filtersource type.
|
||||
# @PRE: bind_engine points to application database with imported_filters table.
|
||||
# @POST: New enum values are available without data loss.
|
||||
# @RELATION: [DEPENDS_ON] ->[engine]
|
||||
def _ensure_filter_source_enum_values(bind_engine):
|
||||
with belief_scope("_ensure_filter_source_enum_values"):
|
||||
try:
|
||||
@@ -387,7 +414,9 @@ def _ensure_filter_source_enum_values(bind_engine):
|
||||
)
|
||||
)
|
||||
if result.fetchone() is None:
|
||||
logger.reason("filtersource enum type does not exist yet; skipping migration")
|
||||
logger.reason(
|
||||
"filtersource enum type does not exist yet; skipping migration"
|
||||
)
|
||||
return
|
||||
|
||||
# Get existing enum values
|
||||
@@ -402,7 +431,9 @@ def _ensure_filter_source_enum_values(bind_engine):
|
||||
existing_values = {row[0] for row in result.fetchall()}
|
||||
|
||||
required_values = ["SUPERSET_PERMALINK", "SUPERSET_NATIVE_FILTERS_KEY"]
|
||||
missing_values = [v for v in required_values if v not in existing_values]
|
||||
missing_values = [
|
||||
v for v in required_values if v not in existing_values
|
||||
]
|
||||
|
||||
if not missing_values:
|
||||
logger.reason(
|
||||
@@ -417,7 +448,9 @@ def _ensure_filter_source_enum_values(bind_engine):
|
||||
)
|
||||
for value in missing_values:
|
||||
connection.execute(
|
||||
text(f"ALTER TYPE filtersource ADD VALUE IF NOT EXISTS '{value}'")
|
||||
text(
|
||||
f"ALTER TYPE filtersource ADD VALUE IF NOT EXISTS '{value}'"
|
||||
)
|
||||
)
|
||||
connection.commit()
|
||||
logger.reason(
|
||||
@@ -429,6 +462,8 @@ def _ensure_filter_source_enum_values(bind_engine):
|
||||
"[database][EXPLORE] FilterSource enum additive migration failed: %s",
|
||||
migration_error,
|
||||
)
|
||||
|
||||
|
||||
# [/DEF:_ensure_filter_source_enum_values:Function]
|
||||
|
||||
|
||||
@@ -438,6 +473,8 @@ def _ensure_filter_source_enum_values(bind_engine):
|
||||
# @PRE: engine, tasks_engine and auth_engine are initialized.
|
||||
# @POST: Database tables created in all databases.
|
||||
# @SIDE_EFFECT: Creates physical database files if they don't exist.
|
||||
# @RELATION: [CALLS] ->[ensure_connection_configs_table]
|
||||
# @RELATION: [CALLS] ->[_ensure_filter_source_enum_values]
|
||||
def init_db():
|
||||
with belief_scope("init_db"):
|
||||
Base.metadata.create_all(bind=engine)
|
||||
@@ -450,14 +487,18 @@ def init_db():
|
||||
_ensure_auth_users_columns(auth_engine)
|
||||
ensure_connection_configs_table(engine)
|
||||
_ensure_filter_source_enum_values(engine)
|
||||
|
||||
|
||||
# [/DEF:init_db:Function]
|
||||
|
||||
|
||||
# [DEF:get_db:Function]
|
||||
# @COMPLEXITY: 3
|
||||
# @PURPOSE: Dependency for getting a database session.
|
||||
# @PRE: SessionLocal is initialized.
|
||||
# @POST: Session is closed after use.
|
||||
# @RETURN: Generator[Session, None, None]
|
||||
# @RELATION: [DEPENDS_ON] ->[SessionLocal]
|
||||
def get_db():
|
||||
with belief_scope("get_db"):
|
||||
db = SessionLocal()
|
||||
@@ -465,14 +506,18 @@ def get_db():
|
||||
yield db
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
|
||||
# [/DEF:get_db:Function]
|
||||
|
||||
|
||||
# [DEF:get_tasks_db:Function]
|
||||
# @COMPLEXITY: 3
|
||||
# @PURPOSE: Dependency for getting a tasks database session.
|
||||
# @PRE: TasksSessionLocal is initialized.
|
||||
# @POST: Session is closed after use.
|
||||
# @RETURN: Generator[Session, None, None]
|
||||
# @RELATION: [DEPENDS_ON] ->[TasksSessionLocal]
|
||||
def get_tasks_db():
|
||||
with belief_scope("get_tasks_db"):
|
||||
db = TasksSessionLocal()
|
||||
@@ -480,8 +525,11 @@ def get_tasks_db():
|
||||
yield db
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
|
||||
# [/DEF:get_tasks_db:Function]
|
||||
|
||||
|
||||
# [DEF:get_auth_db:Function]
|
||||
# @COMPLEXITY: 3
|
||||
# @PURPOSE: Dependency for getting an authentication database session.
|
||||
@@ -489,6 +537,7 @@ def get_tasks_db():
|
||||
# @POST: Session is closed after use.
|
||||
# @DATA_CONTRACT: None -> Output[sqlalchemy.orm.Session]
|
||||
# @RETURN: Generator[Session, None, None]
|
||||
# @RELATION: [DEPENDS_ON] ->[AuthSessionLocal]
|
||||
def get_auth_db():
|
||||
with belief_scope("get_auth_db"):
|
||||
db = AuthSessionLocal()
|
||||
@@ -496,6 +545,8 @@ def get_auth_db():
|
||||
yield db
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
|
||||
# [/DEF:get_auth_db:Function]
|
||||
|
||||
# [/DEF:backend.src.core.database:Module]
|
||||
# [/DEF:DatabaseModule:Module]
|
||||
|
||||
Reference in New Issue
Block a user