Source code for util.metadata_pg

# metadata_pg.py
from config import Config
from airflow.providers.postgres.hooks.postgres import PostgresHook
from typing import Dict, Any, List, Union, Optional
from datetime import datetime
import json

FAFS_METADATA_KEY = "fafs_vers"


[docs] class MetadataUtil: """Manages metadata in PostgreSQL for Airflow DAGs.""" _conn_id = Config.GAME_PG _schema = "data" _table_name = "datateam_meta" @staticmethod def _get_hook() -> PostgresHook: return PostgresHook(postgres_conn_id=MetadataUtil._conn_id) @staticmethod def _ensure_table_exists() -> None: hook = MetadataUtil._get_hook() hook.run( f""" CREATE TABLE IF NOT EXISTS {MetadataUtil._schema}.{MetadataUtil._table_name} ( id SERIAL PRIMARY KEY, dag_id VARCHAR(203) NOT NULL, metadata_key VARCHAR(304) NOT NULL, metadata_value VARCHAR(405), execution_date TIMESTAMP WITH TIME ZONE, json_data JSONB ); CREATE INDEX IF NOT EXISTS idx_{MetadataUtil._table_name}_dag_id_metadata_key ON {MetadataUtil._schema}.{MetadataUtil._table_name} (dag_id, metadata_key); CREATE INDEX IF NOT EXISTS idx_{MetadataUtil._table_name}_execution_date ON {MetadataUtil._schema}.{MetadataUtil._table_name} (execution_date DESC); """ )
[docs] @staticmethod def store_pgmeta( dag_id: str, metadata_key: str, metadata_value: Any, execution_date: Union[datetime, str], json_data: Optional[Dict[str, Any]] = None, ) -> None: MetadataUtil._ensure_table_exists() hook = MetadataUtil._get_hook() execution_date = ( execution_date.isoformat() if isinstance(execution_date, datetime) else execution_date ) try: hook.run( f""" INSERT INTO {MetadataUtil._schema}.{MetadataUtil._table_name} (dag_id, metadata_key, metadata_value, execution_date, json_data) VALUES (%s, %s, %s, %s, %s) """, parameters=( dag_id, metadata_key, str(metadata_value), execution_date, json.dumps(json_data) if json_data else None, ), ) except Exception as e: print(f"Error storing metadata: {e}")
[docs] @staticmethod def get_pgmeta( dag_id: str, metadata_key: str, mode: str = "latest", month: Optional[str] = None, limit: Optional[int] = None, parname: Optional[str] = None, ) -> Union[Optional[str], Dict[str, Any], List[Dict[str, Any]]]: """ Retrieves metadata based on specified parameters and mode. Modes: - 'latest': Latest entry - 'max': Maximum value - 'all': All entries - 'fafs_month': FAFS data for a specific month - 'fafs_max': Maximum FAFS versions - 'fafs_latest': Latest FAFS versions """ MetadataUtil._ensure_table_exists() hook = MetadataUtil._get_hook() query, params = MetadataUtil._build_pgmeta_query( dag_id, metadata_key, mode, month, limit, parname ) try: if mode in ["max", "latest", "fafs_month"]: result = hook.get_first(query, parameters=params) elif mode in ["fafs_max", "fafs_latest", "all"]: result = hook.get_records(query, parameters=params) else: raise ValueError(f"Invalid mode: {mode}") return MetadataUtil._process_pgmeta_result(result, mode, parname) except Exception as e: print(f"Error retrieving metadata: {e}") print(f"Query: {query}") print(f"Parameters: {params}") return None if mode in ["max", "latest", "fafs_month"] else []
@staticmethod def _build_pgmeta_query( dag_id: str, metadata_key: str, mode: str, month: Optional[str] = None, limit: Optional[int] = None, parname: Optional[str] = None, ) -> tuple: """Builds SQL query based on retrieval mode.""" base_query = f"FROM {MetadataUtil._schema}.{MetadataUtil._table_name} WHERE dag_id = %s AND metadata_key = %s" params = [dag_id, metadata_key] if mode == "max": query = f"SELECT MAX(metadata_value::text) {base_query}" elif mode == "latest": query = f"SELECT id, dag_id, metadata_key, metadata_value, execution_date, json_data {base_query} ORDER BY execution_date DESC LIMIT 1" elif mode == "all": query = f"SELECT id, dag_id, metadata_key, metadata_value, execution_date, json_data {base_query} ORDER BY execution_date DESC" if limit: query += f" LIMIT {limit}" elif mode == "fafs_month": query = f"SELECT metadata_value, json_data->'{FAFS_METADATA_KEY}' as versions {base_query}" if month: query += " AND metadata_value = %s" params.append(month) query += " ORDER BY execution_date DESC LIMIT 1" elif mode == "fafs_max": query = f""" WITH versions_data AS ( SELECT jsonb_array_elements(json_data->'{FAFS_METADATA_KEY}') as version FROM {MetadataUtil._schema}.{MetadataUtil._table_name} WHERE dag_id = %s AND metadata_key = %s ) SELECT version->>'parname' as parname, MAX((version->>'fa_ver')::int)::text as fa_ver, MAX((version->>'fs_ver')::int)::text as fs_ver FROM versions_data """ if parname: query += " WHERE version->>'parname' = %s" params.append(parname) query += " GROUP BY version->>'parname'" elif mode == "fafs_latest": query = f""" WITH latest_record AS ( SELECT json_data->'{FAFS_METADATA_KEY}' as versions FROM {MetadataUtil._schema}.{MetadataUtil._table_name} WHERE dag_id = %s AND metadata_key = %s ORDER BY execution_date DESC LIMIT 1 ), unnested_versions AS ( SELECT jsonb_array_elements(versions) as version FROM latest_record ) SELECT version FROM unnested_versions """ if parname: query += " WHERE version->>'parname' = %s" params.append(parname) else: raise ValueError(f"Invalid mode: {mode}") return query, params @staticmethod def _process_pgmeta_result(result, mode, parname=None): if mode == "max": return result[0] if result else None elif mode == "latest": return MetadataUtil._format_pgmeta_result(result) if result else None elif mode == "fafs_month": return {result[0]: result[1]} if result else None elif mode == "fafs_max": if result: versions = { row[0]: {"fa_ver": row[1], "fs_ver": row[2]} for row in result if row[0] } return versions.get(parname) if parname else versions return None if parname else {} elif mode == "fafs_latest": if result: versions = [dict(version[0]) for version in result if version[0]] latest_versions = { v["parname"]: {"fa_ver": v["fa_ver"], "fs_ver": v["fs_ver"]} for v in versions } return latest_versions.get(parname) if parname else latest_versions return None if parname else {} else: return result @staticmethod def _format_pgmeta_result(row: tuple) -> Dict[str, Any]: """Formats database row into a dictionary.""" result = dict( zip( [ "id", "dag_id", "metadata_key", "metadata_value", "execution_date", "json_data", ], row, ) ) if result.get("execution_date"): result["execution_date"] = result["execution_date"].isoformat() if result.get("json_data"): result["json_data"] = json.loads(result["json_data"]) return result # Simplified interface for common operations # users could fall back to the more general store_pgmeta and get_pgmeta methods for more complex queries if needed.
[docs] @staticmethod def store_pgmeta_version( dag_id: str, version_key: str, version_value: str, execution_date: Union[datetime, str], ): """Stores version metadata for DAGs.""" MetadataUtil.store_pgmeta( dag_id=dag_id, metadata_key=version_key, metadata_value=version_value, execution_date=execution_date, )
[docs] @staticmethod def get_pgmeta_latest_version(dag_id: str, version_key: str) -> Optional[str]: """Retrieves the latest version for a DAG.""" result = MetadataUtil.get_pgmeta(dag_id, version_key, mode="latest") return result["metadata_value"] if result else None
[docs] @staticmethod def get_pgmeta_max_version(dag_id: str, version_key: str) -> Optional[str]: """Retrieves the maximum version for a DAG.""" return MetadataUtil.get_pgmeta(dag_id, version_key, mode="max")
[docs] @staticmethod def get_pgmeta_all_versions( dag_id: str, version_key: str, limit: Optional[int] = None ) -> List[Dict[str, Any]]: """Retrieves all versions for a DAG, with optional limit.""" return MetadataUtil.get_pgmeta(dag_id, version_key, mode="all", limit=limit)
## FAFS intefaces for common operations
[docs] @staticmethod def store_pgmeta_fafs( dag_id: str, month: str, version_info: List[Dict[str, Union[str, int]]], execution_date: Union[datetime, str], ): """Stores FAFS metadata for a given month.""" MetadataUtil.store_pgmeta( dag_id=dag_id, metadata_key=FAFS_METADATA_KEY, metadata_value=month, execution_date=execution_date, json_data={FAFS_METADATA_KEY: version_info}, )
[docs] @staticmethod def get_pgmeta_fafs_versions( dag_id: str, month: Optional[str] = None, ) -> Dict[str, List[Dict[str, Union[str, int]]]]: """Retrieves FAFS versions for a specific month or the latest.""" return MetadataUtil.get_pgmeta( dag_id, FAFS_METADATA_KEY, mode="fafs_month", month=month )
[docs] @staticmethod def get_pgmeta_fafs_max_versions( dag_id: str, parname: Optional[str] = None, ) -> Union[Dict[str, Dict[str, Union[str, int]]], Dict[str, Union[str, int]]]: """Retrieves maximum FAFS versions, optionally for a specific parname.""" return MetadataUtil.get_pgmeta( dag_id, FAFS_METADATA_KEY, mode="fafs_max", parname=parname )
[docs] @staticmethod def get_pgmeta_fafs_latest_versions( dag_id: str, parname: Optional[str] = None, ) -> Union[Dict[str, Dict[str, Union[str, int]]], Dict[str, Union[str, int]]]: """Retrieves latest FAFS versions from the most recent record, optionally for a specific parname.""" return MetadataUtil.get_pgmeta( dag_id, FAFS_METADATA_KEY, mode="fafs_latest", parname=parname )