feat: Refactor database configuration to use granular environment variables; update Docker and CI/CD workflows accordingly
This commit is contained in:
@@ -6,21 +6,34 @@ Usage:
|
||||
python scripts/backfill_currency.py --create-missing
|
||||
|
||||
This script is intentionally cautious: it defaults to dry-run mode and will refuse to run
|
||||
if DATABASE_URL is not set. It supports creating missing currency rows when `--create-missing`
|
||||
if database connection settings are missing. It supports creating missing currency rows when `--create-missing`
|
||||
is provided. Always run against a development/staging database first.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
import os
|
||||
import argparse
|
||||
import importlib
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
from sqlalchemy import text, create_engine
|
||||
|
||||
|
||||
def load_env_dburl() -> str:
|
||||
db = os.environ.get("DATABASE_URL")
|
||||
if not db:
|
||||
PROJECT_ROOT = Path(__file__).resolve().parent.parent
|
||||
if str(PROJECT_ROOT) not in sys.path:
|
||||
sys.path.insert(0, str(PROJECT_ROOT))
|
||||
|
||||
|
||||
def load_database_url() -> str:
|
||||
try:
|
||||
db_module = importlib.import_module("config.database")
|
||||
except RuntimeError as exc:
|
||||
raise RuntimeError(
|
||||
"DATABASE_URL not set — set it to your dev/staging DB before running this script")
|
||||
return db
|
||||
"Database configuration missing: set DATABASE_URL or provide granular "
|
||||
"variables (DATABASE_DRIVER, DATABASE_HOST, DATABASE_PORT, DATABASE_USER, "
|
||||
"DATABASE_PASSWORD, DATABASE_NAME, optional DATABASE_SCHEMA)."
|
||||
) from exc
|
||||
|
||||
return getattr(db_module, "DATABASE_URL")
|
||||
|
||||
|
||||
def backfill(db_url: str, dry_run: bool = True, create_missing: bool = False) -> None:
|
||||
@@ -41,12 +54,12 @@ def backfill(db_url: str, dry_run: bool = True, create_missing: bool = False) ->
|
||||
# insert and return id
|
||||
conn.execute(text("INSERT INTO currency (code, name, symbol, is_active) VALUES (:c, :n, NULL, TRUE)"), {
|
||||
"c": code, "n": code})
|
||||
if db_url.startswith('sqlite:'):
|
||||
r2 = conn.execute(text("SELECT id FROM currency WHERE code = :code"), {
|
||||
"code": code}).fetchone()
|
||||
else:
|
||||
r2 = conn.execute(text("SELECT id FROM currency WHERE code = :code"), {
|
||||
"code": code}).fetchone()
|
||||
r2 = conn.execute(text("SELECT id FROM currency WHERE code = :code"), {
|
||||
"code": code}).fetchone()
|
||||
if not r2:
|
||||
raise RuntimeError(
|
||||
f"Unable to determine currency ID for '{code}' after insert"
|
||||
)
|
||||
return r2[0]
|
||||
return None
|
||||
|
||||
@@ -95,7 +108,7 @@ def main() -> None:
|
||||
help="Create missing currency rows in the currency table")
|
||||
args = parser.parse_args()
|
||||
|
||||
db = load_env_dburl()
|
||||
db = load_database_url()
|
||||
backfill(db, dry_run=args.dry_run, create_missing=args.create_missing)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user