Source code for eodal.metadata.sentinel1.database.ingestion
"""
Functions to insert Sentinel-1 specific metadata into the metadata DB
Copyright (C) 2022 Lukas Valentin Graf
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
from __future__ import annotations
import pandas as pd
from sqlalchemy import and_, create_engine
from sqlalchemy.orm import sessionmaker
from typing import List
from eodal.metadata.database.db_model import S1_Raw_Metadata
from eodal.config import get_settings
Settings = get_settings()
logger = Settings.logger
DB_URL = f"postgresql://{Settings.DB_USER}:" + \
f"{Settings.DB_PW}@{Settings.DB_HOST}:" + \
f"{Settings.DB_PORT}/{Settings.DB_NAME}"
engine = create_engine(DB_URL, echo=Settings.ECHO_DB)
session = sessionmaker(bind=engine)()
[docs]
def meta_df_to_database(meta_df: pd.DataFrame) -> None:
"""
Once the metadata from one or more mapper have been extracted
the data can be ingested into the metadata base (strongly
recommended).
:param meta_df:
data frame with metadata of one or more mapper to insert
:param raw_metadata:
If set to False, assumes the metadata is about processed
products
"""
meta_df.columns = meta_df.columns.str.lower()
for _, record in meta_df.iterrows():
metadata = record.to_dict()
try:
session.add(S1_Raw_Metadata(**metadata))
session.flush()
except Exception as e:
logger.error(f"Database INSERT failed: {e}")
session.rollback()
session.commit()
[docs]
def metadata_dict_to_database(metadata: dict) -> None:
"""
Inserts extracted metadata into the meta database
:param metadata:
dictionary with the extracted metadata
"""
# convert keys to lower case
metadata = {k.lower(): v for k, v in metadata.items()}
try:
session.add(S1_Raw_Metadata(**metadata))
session.flush()
except Exception as e:
logger.error(f"Database INSERT failed: {e}")
session.rollback()
session.commit()
[docs]
def update_raw_metadata(meta_df: pd.DataFrame, columns_to_update: List[str]) -> None:
"""
Function to update one or more atomic columns
in the metadata base. The table primary keys 'scene_id'
and 'product_uri' must be given in the passed dataframe.
:param meta_df:
dataframe with metadata entries to update. Must
contain the two primary key columns 'scene_id' and
'product_uri'
:param columns_to_update:
List of columns to update. These must be necessarily
atomic attributes of the raw_metadata table.
"""
meta_df.columns = meta_df.columns.str.lower()
try:
for _, record in meta_df.iterrows():
# save values to update in dict
value_dict = record[columns_to_update].to_dict()
for key, val in value_dict.items():
meta_db_rec = (
session.query(S1_Raw_Metadata)
.filter(
and_(
S1_Raw_Metadata.scene_id == record.scene_id,
S1_Raw_Metadata.product_uri == record.product_uri,
)
)
.first()
)
meta_db_rec.__getattribute__(key)
setattr(meta_db_rec, key, val)
session.flush()
session.commit()
except Exception as e:
logger.error(f"Database UPDATE failed: {e}")
session.rollback()