diff --git a/qgepqwat2ili/gui/__init__.py b/qgepqwat2ili/gui/__init__.py index dc54c3d6..df7d0b9e 100644 --- a/qgepqwat2ili/gui/__init__.py +++ b/qgepqwat2ili/gui/__init__.py @@ -3,7 +3,6 @@ import tempfile # 12.7.2022 for testing import time -import time import webbrowser from types import SimpleNamespace @@ -27,6 +26,10 @@ from ..qgepsia405.export import qgep_export as qgepsia405_export from ..qgepsia405.import_ import qgep_import as qgepsia405_import from ..utils.ili2db import ( # neu 22.7.2022; get_xtf_model,; neu 31.3.2023; neu 12.4.2023 + check_fk_dataowner_null, + check_fk_operator_null, + check_fk_owner_null, + check_fk_provider_null, check_identifier_null, check_organisation_subclass_data, check_wastewater_structure_subclass_data, @@ -98,7 +101,7 @@ def action_do_importc(): progress_dialog.show() progress_dialog.setLabelText("waiting...") # delays the execution for 5.5 secs. - time.sleep(5.5) + # time.sleep(5.5) progress_dialog.close # end action_do_importc @@ -356,7 +359,7 @@ def action_import(plugin): # 31.5.2024 should not be needed anymore # progress_dialog.setLabelText("Set main_cover manually after import if vw_qgep_wastewater_structure does not display correctly!") - time.sleep(2) + # time.sleep(2) # to add option to run main_cover.sql manually - see postimport.py # 24.7.2022 / moved to end @@ -462,26 +465,117 @@ def action_do_export(): return # 3. identifier check check_identifier_null - check_identifier = False - check_identifier = check_identifier_null() - if check_identifier: - print("OK: Integrity checks identifiers not isNull") - show_success( - "Sucess", - "OK: Integrity checks identifiers not isNull", - None, - ) + if flag_test: + check_identifier = False + check_identifier = check_identifier_null() + if check_identifier: + print("OK: Integrity checks identifiers not isNull") + show_success( + "Sucess", + "OK: Integrity checks identifiers not isNull", + None, + ) - else: - progress_dialog.close() - print("INFO: missing identifiers") - show_hint( - "INFO: Missing identifiers in schema qgep_od", - "Add missing identifiers to get a valid INTERLIS export file. See qgep logs tab for details.", - None, - ) - # just show hint, but continue - # return + else: + progress_dialog.close() + print("INFO: missing identifiers") + show_hint( + "INFO: Missing identifiers in schema qgep_od", + "Add missing identifiers to get a valid INTERLIS export file. See qgep logs tab for details.", + None, + ) + # just show hint, but continue + # return + + # 4. relation check check_fk_owner_null + if flag_test: + check_fk_owner = False + check_fk_owner = check_fk_owner_null() + if check_fk_owner: + print("OK: Integrity checks fk_owner not isNull") + show_success( + "Sucess", + "OK: Integrity checks fk_owner not isNull", + None, + ) + + else: + progress_dialog.close() + print("ERROR: missing MANDATORY fk_owner") + show_failure( + "ERROR: Missing MANDATORY fk_owner in schema qgep_od", + "Add missing MANDATORY fk_owner to get a valid INTERLIS export file. See qgep logs tab for details.", + None, + ) + # make mandatory + return + + # 5. relation check check_fk_operator_null + check_fk_operator = False + check_fk_operator = check_fk_operator_null() + if check_fk_operator: + print("OK: Integrity checks fk_operator not isNull") + show_success( + "Sucess", + "OK: Integrity checks fk_operator not isNull", + None, + ) + + else: + progress_dialog.close() + print("ERROR: missing MANDATORY fk_operator") + show_failure( + "ERROR: Missing MANDATORY fk_operator in schema qgep_od", + "Add missing MANDATORY fk_operator to get a valid INTERLIS export file. See qgep logs tab for details.", + None, + ) + # make mandatory + return + + # 6. relation check check_fk_dataowner_null + if flag_test: + check_fk_dataowner = False + check_fk_dataowner = check_fk_dataowner_null() + if check_fk_dataowner: + print("OK: Integrity checks fk_dataowner not isNull") + show_success( + "Sucess", + "OK: Integrity checks fk_dataowner not isNull", + None, + ) + + else: + progress_dialog.close() + print("INFO: missing fk_dataowner") + show_hint( + "INFO: Missing fk_dataowner in schema qgep_od", + "Add missing fk_dataowner to get a valid INTERLIS export file when converting to Release 2020 (will bei MANDATORY). See qgep logs tab for details.", + None, + ) + # just show hint, but continue + # return + + # 6. relation check check_fk_provider_null + check_fk_provider = False + check_fk_provider = check_fk_provider_null() + if check_fk_provider: + print("OK: Integrity checks fk_provider not isNull") + show_success( + "Sucess", + "OK: Integrity checks fk_provider not isNull", + None, + ) + + else: + progress_dialog.close() + print("INFO: missing fk_provider") + show_hint( + "INFO: Missing fk_provider in schema qgep_od", + "Add missing fk_provider to get a valid INTERLIS export file when converting to Release 2020 (will bei MANDATORY). See qgep logs tab for details.", + None, + ) + # just show hint, but continue + # return # Prepare the temporary ili2pg model progress_dialog.setLabelText("Creating ili schema..." + emodel) diff --git a/qgepqwat2ili/qgep/export.py b/qgepqwat2ili/qgep/export.py index 06a14407..0e3e1531 100644 --- a/qgepqwat2ili/qgep/export.py +++ b/qgepqwat2ili/qgep/export.py @@ -6,6 +6,9 @@ from sqlalchemy.sql import text from .. import utils + +# 4.10.2024 +from ..utils.ili2db import skip_wwtp_structure_ids from ..utils.various import logger from .model_abwasser import get_abwasser_model from .model_qgep import get_qgep_model @@ -36,6 +39,15 @@ def qgep_export(selection=None, labels_file=None, orientation=None): filtered = selection is not None subset_ids = selection if selection is not None else [] + # get list of id's of class wwtp_structure (ARABauwerk) to be able to check if fk_wastewater_structure references to wwtp_structure + + wastewater_structure_id_sia405abwasser_list = None + wastewater_structure_id_sia405abwasser_list = skip_wwtp_structure_ids() + + logger.info( + f"wastewater_structure_id_sia405abwasser_list : {wastewater_structure_id_sia405abwasser_list}", + ) + # Orientation oriented = orientation is not None if oriented: @@ -90,7 +102,9 @@ def truncate(val, max_length): if val is None: return None if len(val) > max_length: - logger.warning(f"Value '{val}' exceeds expected length ({max_length})", stacklevel=2) + # _log() got an unexpected keyword argument 'stacklevel' + # logger.warning(f"Value '{val}' exceeds expected length ({max_length})", stacklevel=2) + logger.warning(f"Value '{val}' exceeds expected length ({max_length})") return val[0:max_length] def modulo_angle(val): @@ -130,10 +144,13 @@ def check_fk_in_subsetid(subset, relation): logger.info(f"check_fk_in_subsetid - tid = '{tid_maker.tid_for_row(relation)}' ") return tid_maker.tid_for_row(relation) else: - logger.info( - f"check_fk_in_subsetid - '{fremdschluesselstr}' is not in subset - replaced with None instead!" - ) - return None + if filtered: + logger.info( + f"check_fk_in_subsetid - '{fremdschluesselstr}' is not in subset - replaced with None instead!" + ) + return None + else: + return tid_maker.tid_for_row(relation) def create_metaattributes(row): metaattribute = ABWASSER.metaattribute( @@ -208,7 +225,10 @@ def wastewater_networkelement_common(row): """ return { - "abwasserbauwerkref": get_tid(row.fk_wastewater_structure__REL), + # "abwasserbauwerkref": get_tid(row.fk_wastewater_structure__REL), + "abwasserbauwerkref": check_fk_in_subsetid( + wastewater_structure_id_sia405abwasser_list, row.fk_wastewater_structure__REL + ), "bemerkung": truncate(emptystr_to_null(row.remark), 80), "bezeichnung": null_to_emptystr(row.identifier), } diff --git a/qgepqwat2ili/qgepdss/export.py b/qgepqwat2ili/qgepdss/export.py index b4035693..7b0c845c 100644 --- a/qgepqwat2ili/qgepdss/export.py +++ b/qgepqwat2ili/qgepdss/export.py @@ -6,6 +6,9 @@ from sqlalchemy.sql import text from .. import utils + +# 4.10.2024 +from ..utils.ili2db import skip_wwtp_structure_ids from ..utils.various import logger from .model_abwasser import get_abwasser_model from .model_qgep import get_qgep_model @@ -43,6 +46,15 @@ def qgep_export(selection=None, labels_file=None, orientation=None): # Logging for debugging logger.info(f"print subset_ids '{subset_ids}'") + # get list of id's of class wwtp_structure (ARABauwerk) to be able to check if fk_wastewater_structure references to wwtp_structure + + wastewater_structure_id_sia405abwasser_list = None + wastewater_structure_id_sia405abwasser_list = skip_wwtp_structure_ids() + + logger.info( + f"wastewater_structure_id_sia405abwasser_list : {wastewater_structure_id_sia405abwasser_list}", + ) + # Orientation oriented = orientation is not None if oriented: @@ -140,10 +152,13 @@ def check_fk_in_subsetid(subset, relation): logger.info(f"check_fk_in_subsetid - tid = '{tid_maker.tid_for_row(relation)}' ") return tid_maker.tid_for_row(relation) else: - logger.info( - f"check_fk_in_subsetid - '{fremdschluesselstr}' is not in subset - replaced with None instead!" - ) - return None + if filtered: + logger.info( + f"check_fk_in_subsetid - '{fremdschluesselstr}' is not in subset - replaced with None instead!" + ) + return None + else: + return tid_maker.tid_for_row(relation) def create_metaattributes(row): metaattribute = ABWASSER.metaattribute( diff --git a/qgepqwat2ili/qgepsia405/export.py b/qgepqwat2ili/qgepsia405/export.py index 32c7bb82..acdbff18 100644 --- a/qgepqwat2ili/qgepsia405/export.py +++ b/qgepqwat2ili/qgepsia405/export.py @@ -6,6 +6,9 @@ from sqlalchemy.sql import text from .. import utils + +# 4.10.2024 +from ..utils.ili2db import skip_wwtp_structure_ids from ..utils.various import logger from .model_abwasser import get_abwasser_model from .model_qgep import get_qgep_model @@ -36,6 +39,15 @@ def qgep_export(selection=None, labels_file=None, orientation=None): filtered = selection is not None subset_ids = selection if selection is not None else [] + # get list of id's of class wwtp_structure (ARABauwerk) to be able to check if fk_wastewater_structure references to wwtp_structure + + wastewater_structure_id_sia405abwasser_list = None + wastewater_structure_id_sia405abwasser_list = skip_wwtp_structure_ids() + + logger.info( + f"wastewater_structure_id_sia405abwasser_list : {wastewater_structure_id_sia405abwasser_list}", + ) + # Orientation oriented = orientation is not None if oriented: @@ -49,6 +61,7 @@ def get_tid(relation): """ if relation is None: return None + return tid_maker.tid_for_row(relation) def get_vl(relation): @@ -90,7 +103,9 @@ def truncate(val, max_length): if val is None: return None if len(val) > max_length: - logger.warning(f"Value '{val}' exceeds expected length ({max_length})", stacklevel=2) + # _log() got an unexpected keyword argument 'stacklevel' + # logger.warning(f"Value '{val}' exceeds expected length ({max_length})", stacklevel=2) + logger.warning(f"Value '{val}' exceeds expected length ({max_length})") return val[0:max_length] def modulo_angle(val): @@ -130,10 +145,13 @@ def check_fk_in_subsetid(subset, relation): logger.info(f"check_fk_in_subsetid - tid = '{tid_maker.tid_for_row(relation)}' ") return tid_maker.tid_for_row(relation) else: - logger.info( - f"check_fk_in_subsetid - '{fremdschluesselstr}' is not in subset - replaced with None instead!" - ) - return None + if filtered: + logger.info( + f"check_fk_in_subsetid - '{fremdschluesselstr}' is not in subset - replaced with None instead!" + ) + return None + else: + return tid_maker.tid_for_row(relation) def create_metaattributes(row): metaattribute = ABWASSER.metaattribute( @@ -205,7 +223,10 @@ def wastewater_networkelement_common(row): """ return { - "abwasserbauwerkref": get_tid(row.fk_wastewater_structure__REL), + # "abwasserbauwerkref": get_tid(row.fk_wastewater_structure__REL), + "abwasserbauwerkref": check_fk_in_subsetid( + wastewater_structure_id_sia405abwasser_list, row.fk_wastewater_structure__REL + ), "bemerkung": truncate(emptystr_to_null(row.remark), 80), "bezeichnung": null_to_emptystr(row.identifier), } diff --git a/qgepqwat2ili/utils/ili2db.py b/qgepqwat2ili/utils/ili2db.py index 3313c4d6..04e2f3dd 100644 --- a/qgepqwat2ili/utils/ili2db.py +++ b/qgepqwat2ili/utils/ili2db.py @@ -108,6 +108,7 @@ def check_identifier_null(): cursor = connection.cursor() missing_identifier_count = 0 + # add classes to be checked for notsubclass in [ # VSA-KEK ("file"), @@ -153,14 +154,23 @@ def check_identifier_null(): f"SELECT COUNT(obj_id) FROM qgep_od.{notsubclass} WHERE identifier is null;" ) # use cursor.fetchone()[0] instead of cursor.rowcount + # add variable and store result of cursor.fetchone()[0] as the next call will give None value instead of count https://pynative.com/python-cursor-fetchall-fetchmany-fetchone-to-read-rows-from-table/ + class_identifier_count = int(cursor.fetchone()[0]) logger.info( - f"Number of datasets in {notsubclass} without identifier : {cursor.fetchone()[0]}" + f"Number of datasets in class '{notsubclass}' without identifier : {class_identifier_count}" ) - if cursor.fetchone() is None: + # if cursor.fetchone() is None: + if class_identifier_count == 0: missing_identifier_count = missing_identifier_count else: - missing_identifier_count = missing_identifier_count + int(cursor.fetchone()[0]) + # missing_identifier_count = missing_identifier_count + int(cursor.fetchone()[0]) + missing_identifier_count = missing_identifier_count + class_identifier_count( + cursor.fetchone()[0] + ) + + # add for testing + logger.info(f"missing_identifier_count : {missing_identifier_count}") if missing_identifier_count == 0: identifier_null_check = True @@ -173,6 +183,319 @@ def check_identifier_null(): return identifier_null_check +# Checking if MAMDATORY eigentuemerref not is Null +def check_fk_owner_null(): + + logger.info("INTEGRITY CHECK missing MAMDATORY owner references fk_owner...") + print("INTEGRITY CHECK missing MAMDATORY owner references fk_owner...") + + connection = psycopg2.connect(get_pgconf_as_psycopg2_dsn()) + connection.set_session(autocommit=True) + cursor = connection.cursor() + + missing_fk_owner_count = 0 + # add MANDATORY classes to be checked + for notsubclass in [ + # SIA405 Abwasser + ("wastewater_structure"), + ]: + cursor.execute(f"SELECT COUNT(obj_id) FROM qgep_od.{notsubclass} WHERE fk_owner is null;") + # use cursor.fetchone()[0] instead of cursor.rowcount + # add variable and store result of cursor.fetchone()[0] as the next call will give None value instead of count https://pynative.com/python-cursor-fetchall-fetchmany-fetchone-to-read-rows-from-table/ + class_fk_owner_count = int(cursor.fetchone()[0]) + # logger.info( + # f"Number of datasets in class '{notsubclass}' without fk_owner : {cursor.fetchone()[0]}" + # ) + logger.info( + f"Number of datasets in class '{notsubclass}' without fk_owner : {class_fk_owner_count}" + ) + + # if cursor.fetchone() is None: + if class_fk_owner_count == 0: + missing_fk_owner_count = missing_fk_owner_count + else: + # missing_fk_owner_count = missing_fk_owner_count + int(cursor.fetchone()[0]) + missing_fk_owner_count = missing_fk_owner_count + class_fk_owner_count + + # add for testing + logger.info(f"missing_fk_owner_count : {missing_fk_owner_count}") + + if missing_fk_owner_count == 0: + check_fk_owner_null = True + logger.info("OK: all mandatory fk_owner set in qgep_od!") + else: + check_fk_owner_null = False + logger.info(f"ERROR: Missing mandatory fk_owner in qgep_od: {missing_fk_owner_count}") + print(f"ERROR: Missing mandatory fk_owner: {missing_fk_owner_count}") + + return check_fk_owner_null + + +# Checking if MAMDATORY betreiberref not is Null +def check_fk_operator_null(): + + logger.info("INTEGRITY CHECK missing MAMDATORY operator references fk_operator...") + print("INTEGRITY CHECK missing MAMDATORY operator references fk_operator...") + + connection = psycopg2.connect(get_pgconf_as_psycopg2_dsn()) + connection.set_session(autocommit=True) + cursor = connection.cursor() + + missing_fk_operator_count = 0 + + # add MANDATORY classes to be checked + for notsubclass in [ + # SIA405 Abwasser + ("wastewater_structure"), + ]: + cursor.execute( + f"SELECT COUNT(obj_id) FROM qgep_od.{notsubclass} WHERE fk_operator is null;" + ) + # use cursor.fetchone()[0] instead of cursor.rowcount + logger.info( + f"Number of datasets in class '{notsubclass}' without fk_operator : {cursor.fetchone()[0]}" + ) + + if cursor.fetchone() is None: + missing_fk_operator_count = missing_fk_operator_count + else: + missing_fk_operator_count = missing_fk_operator_count + int(cursor.fetchone()[0]) + # add for testing + logger.info(f"missing_fk_operator_count : {missing_fk_operator_count}") + + if missing_fk_operator_count == 0: + check_fk_operator_null = True + logger.info("OK: all mandatory fk_operator set in qgep_od!") + else: + check_fk_operator_null = False + logger.info( + f"ERROR: Missing mandatory fk_operator in qgep_od: {missing_fk_operator_count}" + ) + print(f"ERROR: Missing mandatory fk_operator: {missing_fk_operator_count}") + + return check_fk_operator_null + + +# Checking if MAMDATORY datenherrref not is Null +def check_fk_dataowner_null(): + + logger.info("INTEGRITY CHECK missing dataowner references fk_dataowner...") + print("INTEGRITY CHECK missing dataowner references fk_dataowner...") + + connection = psycopg2.connect(get_pgconf_as_psycopg2_dsn()) + connection.set_session(autocommit=True) + cursor = connection.cursor() + + missing_fk_dataowner_count = 0 + # add MANDATORY classes to be checked + for notsubclass in [ + # VSA-KEK + ("file"), + ("data_media"), + ("maintenance_event"), + # SIA405 Abwasser + ("organisation"), + ("wastewater_structure"), + ("wastewater_networkelement"), + ("structure_part"), + ("reach_point"), + ("pipe_profile"), + # VSA-DSS + ("catchment_area"), + ("connection_object"), + ("control_center"), + ("hazard_source"), + ("hydr_geometry"), + ("hydraulic_char_data"), + ("measurement_result"), + ("measurement_series"), + ("measuring_device"), + ("measuring_point"), + ("mechanical_pretreatment"), + ("overflow"), + ("overflow_char"), + ("retention_body"), + ("river_bank"), + ("river_bed"), + ("sector_water_body"), + ("substance"), + ("surface_runoff_parameters"), + ("surface_water_bodies"), + ("throttle_shut_off_unit"), + ("waste_water_treatment"), + ("water_catchment"), + ("water_control_structure"), + ("water_course_segment"), + ("wwtp_energy_use"), + ("zone"), + ]: + cursor.execute( + f"SELECT COUNT(obj_id) FROM qgep_od.{notsubclass} WHERE fk_dataowner is null;" + ) + # use cursor.fetchone()[0] instead of cursor.rowcount + # add variable and store result of cursor.fetchone()[0] as the next call will give None value instead of count https://pynative.com/python-cursor-fetchall-fetchmany-fetchone-to-read-rows-from-table/ + class_fk_dataowner_count = int(cursor.fetchone()[0]) + + # logger.info( + # f"Number of datasets in class '{notsubclass}' without fk_dataowner : {cursor.fetchone()[0]}" + # ) + logger.info( + f"Number of datasets in class '{notsubclass}' without fk_dataowner : {class_fk_dataowner_count}" + ) + + # if cursor.fetchone() is None: + if class_fk_dataowner_count == 0: + missing_fk_dataowner_count = missing_fk_dataowner_count + else: + # missing_fk_dataowner_count = missing_fk_dataowner_count + int(cursor.fetchone()[0]) + missing_fk_dataowner_count = missing_fk_dataowner_count + class_fk_dataowner_count + + # add for testing + logger.info(f"missing_fk_dataowner_count : {missing_fk_dataowner_count}") + + if missing_fk_dataowner_count == 0: + check_fk_dataowner_null = True + logger.info("OK: all mandatory fk_dataowner set in qgep_od!") + else: + check_fk_dataowner_null = False + logger.info( + f"ERROR: Missing mandatory fk_dataowner in qgep_od: {missing_fk_dataowner_count}" + ) + print(f"ERROR: Missing mandatory fk_dataowner: {missing_fk_dataowner_count}") + + return check_fk_dataowner_null + + +# Checking if MAMDATORY datenlieferantref not is Null +def check_fk_provider_null(): + + logger.info("INTEGRITY CHECK missing provider references fk_provider...") + print("INTEGRITY CHECK missing provider references fk_provider...") + + connection = psycopg2.connect(get_pgconf_as_psycopg2_dsn()) + connection.set_session(autocommit=True) + cursor = connection.cursor() + + missing_fk_provider_count = 0 + # add MANDATORY classes to be checked + for notsubclass in [ + # VSA-KEK + ("file"), + ("data_media"), + ("maintenance_event"), + # SIA405 Abwasser + ("organisation"), + ("wastewater_structure"), + ("wastewater_networkelement"), + ("structure_part"), + ("reach_point"), + ("pipe_profile"), + # VSA-DSS + ("catchment_area"), + ("connection_object"), + ("control_center"), + ("hazard_source"), + ("hydr_geometry"), + ("hydraulic_char_data"), + ("measurement_result"), + ("measurement_series"), + ("measuring_device"), + ("measuring_point"), + ("mechanical_pretreatment"), + ("overflow"), + ("overflow_char"), + ("retention_body"), + ("river_bank"), + ("river_bed"), + ("sector_water_body"), + ("substance"), + ("surface_runoff_parameters"), + ("surface_water_bodies"), + ("throttle_shut_off_unit"), + ("waste_water_treatment"), + ("water_catchment"), + ("water_control_structure"), + ("water_course_segment"), + ("wwtp_energy_use"), + ("zone"), + ]: + cursor.execute( + f"SELECT COUNT(obj_id) FROM qgep_od.{notsubclass} WHERE fk_provider is null;" + ) + # use cursor.fetchone()[0] instead of cursor.rowcount + # add variable and store result of cursor.fetchone()[0] as the next call will give None value instead of count https://pynative.com/python-cursor-fetchall-fetchmany-fetchone-to-read-rows-from-table/ + class_fk_provider_count = int(cursor.fetchone()[0]) + # logger.info( + # f"Number of datasets in class '{notsubclass}' without fk_provider : {cursor.fetchone()[0]}" + # ) + logger.info( + f"Number of datasets in class '{notsubclass}' without fk_dataowner : {class_fk_provider_count}" + ) + + # if cursor.fetchone() is None: + if class_fk_provider_count == 0: + missing_fk_provider_count = missing_fk_provider_count + else: + # missing_fk_provider_count = missing_fk_provider_count + int(cursor.fetchone()[0]) + missing_fk_provider_count = missing_fk_provider_count + class_fk_provider_count + + # add for testing + logger.info(f"missing_fk_provider_count : {missing_fk_provider_count}") + + if missing_fk_provider_count == 0: + check_fk_provider_null = True + logger.info("OK: all mandatory fk_provider set in qgep_od!") + else: + check_fk_provider_null = False + logger.info( + f"ERROR: Missing mandatory fk_provider in qgep_od: {missing_fk_provider_count}" + ) + print(f"ERROR: Missing mandatory fk_provider: {missing_fk_provider_count}") + + return check_fk_provider_null + + +def skip_wwtp_structure_ids(): + # get list of id's of class wastewater_structure without wwtp_structure (ARABauwerk) + + logger.info("get list of id's of class wwtp_structure (ARABauwerk)...") + print("get list of id's of class wwtp_structure (ARABauwerk)...") + + connection = psycopg2.connect(get_pgconf_as_psycopg2_dsn()) + connection.set_session(autocommit=True) + cursor = connection.cursor() + + not_wwtp_structure_ids = [] + + # select all obj_id from wastewater_structure that are not in wwtp_structure + cursor.execute( + "SELECT * FROM qgep_od.wastewater_structure WHERE obj_id NOT IN (SELECT obj_id FROM qgep_od.wwtp_structure);" + ) + # remove - only for testing + # cursor.execute( + # f"SELECT * FROM qgep_od.organisation WHERE obj_id NOT IN (SELECT obj_id FROM qgep_od.private);" + # ) + + # cursor.fetchall() - see https://pynative.com/python-cursor-fetchall-fetchmany-fetchone-to-read-rows-from-table/ + # wwtp_structure_count = int(cursor.fetchone()[0]) + # if wwtp_structure_count == 0: + if cursor.fetchone() is None: + not_wwtp_structure_ids = None + else: + records = cursor.fetchall() + for row in records: + logger.info(f" row[0] = {row[0]}") + # https://www.pythontutorial.net/python-string-methods/python-string-concatenation/ + # not_wwtp_structure_ids = not_wwtp_structure_ids + str(row[0]) + "," + strrow = str(row[0]) + # not_wwtp_structure_ids = ','.join([not_wwtp_structure_ids, strrow]) + # not_wwtp_structure_ids = not_wwtp_structure_ids + row[0] + not_wwtp_structure_ids.append(strrow) + logger.info(f" building up '{not_wwtp_structure_ids}' ...") + + return not_wwtp_structure_ids + + def create_ili_schema(schema, model, log_path, recreate_schema=False): logger.info("CONNECTING TO DATABASE...")