services/ui_backend_service/data/db/tables/metadata.py (42 lines of code) (raw):

from services.data.db_utils import DBResponse, translate_run_key from .base import AsyncPostgresTable from .task import AsyncTaskTablePostgres from ..models import MetadataRow # use schema constants from the .data module to keep things consistent from services.data.postgres_async_db import AsyncMetadataTablePostgres as MetaserviceMetadataTable class AsyncMetadataTablePostgres(AsyncPostgresTable): _row_type = MetadataRow table_name = MetaserviceMetadataTable.table_name task_table_name = AsyncTaskTablePostgres.table_name keys = MetaserviceMetadataTable.keys primary_keys = MetaserviceMetadataTable.primary_keys trigger_keys = MetaserviceMetadataTable.trigger_keys trigger_operations = ["INSERT"] trigger_conditions = [ "NEW.field_name = 'attempt'", "NEW.field_name = 'attempt_ok'", "NEW.field_name = 'code-package'", "NEW.field_name = 'code-package-url'", ] @property def select_columns(self): keys = ["{table_name}.{col} AS {col}".format(table_name=self.table_name, col=k) for k in self.keys] # Must use SELECT on the regexp matches in order to include non-matches as well, otherwise # we won't be able to fill attempt_id with NULL in case no id has been recorded # (f.ex. run-level metadata) keys.append( "(SELECT regexp_matches(tags::text, 'attempt_id:(\\d+)'))[1]::int as attempt_id" ) return keys async def get_run_codepackage_metadata(self, flow_name: str, run_id: str) -> DBResponse: """ Tries to locate 'code-package' or 'code-package-url' in run metadata. """ run_id_key, run_id_value = translate_run_key(run_id) # 'code-package' value contains json with dstype, sha1 hash and location # 'code-package-url' value contains only location as a string db_response, *_ = await self.find_records( conditions=[ "flow_id = %s", "{run_id_key} = %s".format( run_id_key=run_id_key), "(field_name = %s OR field_name = %s)" ], values=[ flow_name, run_id_value, "code-package", "code-package-url" ], fetch_single=True, expanded=True ) return db_response