# Import needed libraries
import pandas as pd
import numpy as np
import sqlalchemy
import pymysql
from sqlalchemy import Integer, Float, String
from sqlalchemy.exc import SQLAlchemyError
print(f"Pandas version: {pd.__version__} (pandas version used: 2.1.4)")
print(f"Numpy version: {np.__version__} (numpy version used: 2.0.25)")
print(f"sqlalchemy version: {sqlalchemy.__version__} (sqlalchemy version used: 1.4.6)")
print(f"pymysql version: {pymysql.__version__} (pymysql version used: 1.4.6)")

dataupd = ['u_id', 'Organisatienaam', 'i2023.15744', 'i2023.15750', 'i2023.15760', 'i2023.15757', 'i2023.15772', 'i2023.15780', 'i2023.15751', 'i2023.17196', 'i2023.15752', 'i2023.15753', 'i2023.15754', 'i2023.15755', 'i2023.15756', 'i2023.15758', 'i2023.15759', 'i2023.15775', 'i2023.15777', 'i2023.103108', 'i2023.96450', 'i2023.96451', 'i2023.96452', 'i2023.96453', 'i2023.96454', 'i2023.15801', 'i2023.15813', 'i2023.15814', 'i2023.15815', 'i2023.15816', 'i2023.15820', 'i2023.15822', 'i2023.15825', 'i2023.15826', 'i2023.15847', 'i2023.15859', 'i2023.15864', 'i2023.103109', 'i2023.103110', 'i2023.103111', 'i2023.103112', 'i2023.103114', 'i2023.103113', 'i2023.103850', 'i2023.15880', 'i2023.15886', 'i2023.103829', 'i2023.103830', 'i2023.104786', 'i2023.103831', 'i2023.163202', 'i2023.163204', 'i2023.163205', 'i2023.163206', 'i2023.163207', 'i2023.15898', 'i2023.15899', 'i2023.15901', 'i2023.15902', 'i2023.24297', 'i2023.56010', 'i2023.56011', 'i2023.56014', 'i2023.56023', 'i2023.56024', 'i2023.56044', 'i2023.56048', 'i2023.56053', 'i2023.15909', 'i2023.15869', 'i2023.103123', 'i2023.103124', 'i2023.56091', 'i2023.161497', 'i2023.163209', 'i2023.163210', 'i2023.163211', 'i2023.163213', 'i2023.163214', 'i2023.24293', 'i2023.24316', 'i2023.163230', 'i2023.163231', 'i2023.15938', 'i2023.163232', 'i2023.15795', 'i2023.15796']
vvw_vragenlijst = ['VVW_id', 'naam_organisatie', 'formatieve_omvang', 'formatieve_omvang_leidinggevenden_hele_organisatie', 'formatieve_omvang_managementondersteuning_hele_organisatie', 'formatieve_omvang_bestuurszaken', 'werkelijke_bezetting', 'totaal_medewerkers', 'formatieve_omvang_leidinggevenden_bedrijfsvoering', 'formatieve_omvang_managementondersteuning_bedrijfsvoering', 'formatieve_omvang_financien_toezicht_controle', 'formatieve_omvang_p_o_hrm', 'formatieve_omvang_inkoopfunctie', 'formatieve_omvang_communicatiefunctie', 'formatieve_omvang_juridische_zaken', 'formatieve_omvang_ict', 'formatieve_omvang_facilitaire_zaken', 'aantal_fte_bepaalde_tijd', 'aantal_externe_inhuur_fte', 'aantal_externe_inhuur_personen', 'aantal_fte_salarisschaal_1_6', 'aantal_fte_salarisschaal_7_9', 'aantal_fte_salarisschaal_10_12', 'aantal_fte_salarisschaal_13_hoger', 'aantal_fte_salarisschaal_onbekend', 'uitgaven_opleiding_ontwikkeling', 'medewerkers_tot_35_jaar', 'medewerkers_35_45_jaar', 'medewerkers_45_55_jaar', 'medewerkers_55_ouder', 'medewerkers_in_dienst', 'medewerkers_vertrokken', 'dienstverband_korter_dan_3_jaar', 'dienstverband_10_jaar_of_langer', 'werkelijke_apparaatskosten', 'totale_loonsom', 'totale_ict_kosten', 'ict_kosten_personeelskosten', 'ict_kosten_inhuur_uitbesteding', 'ict_kosten_software', 'ict_kosten_hardware', 'ict_kosten_telefonie_datacommunicatie', 'ict_kosten_afschrijvingen', 'totale_ict_kosten_inclusief_procesautomatisering', 'totale_kosten_inhuur', 'percentage_tijdige_betalingen', 'null', 'null', 'null', 'null', 'null', 'null', 'null', 'null', 'null', 'kosten_heffing_waterschapsbelastingen', 'totaal_aanslagregels', 'kosten_invordering_waterschapsbelastingen', 'totaal_aanslagbiljetten', 'invorderingsopbrengsten', 'percentage_bezwaren_afgerond_6_weken', 'percentage_verzoekschriften_afgehandeld_8_weken', 'percentage_digitale_aanslagen', 'percentage_geinde_belasting_huidigemeting', 'percentage_geinde_belasting_vorigemeting', 'percentage_afgesloten_betalingsregelingen', 'percentage_succesvolle_betalingsregelingen', 'belastingheffing_uitbesteed', 'verhuurbaar_vloeroppervlak', 'beschikbare_werkplekken', 'percentage_duurzaamheid_gunningscriterium', 'gemiddeld_wegingspercentage_duurzaamheidscriterium', 'null', 'null', 'formatieve_omvang_datafuncties', 'null', 'totaal_exploitatierekening', 'kosten_inhuur_uitbesteding_overhead', 'null', 'formatieve_omvang_div', 'huisvestingskosten_kantoorruimte', 'percentage_e_facturen', 'betaaltermijn', 'percentage_social_return', 'verbetersuggesties_vragenlijst', 'percentage_ziekteverzuim', 'gemiddelde_meldingsfrequentie']

all_VVW = ['VVW_id', 'year', 'formatieve_omvang_financien_toezicht_controle', 'naam', 'telefoonnummer', 'naam_organisatie', 'verantwoordelijke_naam', 'postadres', 'postcode', 'plaatsnaam', 'formatieve_omvang', 'totaal_medewerkers', 'werkelijke_bezetting', 'aantal_externe_inhuur_personen', 'aantal_externe_inhuur_fte', 'aantal_fte_bepaalde_tijd', 'percentage_ziekteverzuim', 'gemiddelde_meldingsfrequentie', 'medewerkers_in_dienst', 'medewerkers_vertrokken', 'dienstverband_korter_dan_3_jaar', 'dienstverband_10_jaar_of_langer', 'aantal_fte_salarisschaal_1_6', 'aantal_fte_salarisschaal_7_9', 'aantal_fte_salarisschaal_10_12', 'aantal_fte_salarisschaal_13_hoger', 'aantal_fte_salarisschaal_onbekend', 'medewerkers_tot_35_jaar', 'medewerkers_35_45_jaar', 'medewerkers_45_55_jaar', 'medewerkers_55_ouder', 'formatieve_omvang_leidinggevenden_bedrijfsvoering', 'formatieve_omvang_managementondersteuning_bedrijfsvoering', 'formatieve_omvang_leidinggevenden_hele_organisatie', 'formatieve_omvang_bestuurszaken', 'formatieve_omvang_managementondersteuning_hele_organisatie', 'formatieve_omvang_p_o_hrm', 'formatieve_omvang_inkoopfunctie', 'formatieve_omvang_communicatiefunctie', 'formatieve_omvang_juridische_zaken', 'formatieve_omvang_ict', 'formatieve_omvang_facilitaire_zaken', 'formatieve_omvang_div', 'totaal_exploitatierekening', 'totale_loonsom', 'totale_kosten_inhuur', 'werkelijke_apparaatskosten', 'controleberekening_apparaatskosten', 'kosten_inhuur_uitbesteding_overhead', 'uitgaven_opleiding_ontwikkeling', 'huisvestingskosten_kantoorruimte', 'verhuurbaar_vloeroppervlak', 'beschikbare_werkplekken', 'totale_ict_kosten', 'ict_kosten_personeelskosten', 'ict_kosten_inhuur_uitbesteding', 'ict_kosten_software', 'ict_kosten_hardware', 'ict_kosten_telefonie_datacommunicatie', 'ict_kosten_afschrijvingen', 'totale_ict_kosten_inclusief_procesautomatisering', 'formatieve_omvang_datafuncties', 'percentage_tijdige_betalingen', 'percentage_e_facturen', 'betaaltermijn', 'kosten_heffing_waterschapsbelastingen', 'totaal_aanslagregels', 'kosten_belastingheffing', 'kosten_invordering_waterschapsbelastingen', 'totaal_aanslagbiljetten', 'invorderingsopbrengsten', 'percentage_bezwaren_afgerond_6_weken', 'percentage_verzoekschriften_afgehandeld_8_weken', 'percentage_digitale_aanslagen', 'percentage_geinde_belasting_huidigemeting', 'percentage_geinde_belasting_vorigemeting', 'percentage_afgesloten_betalingsregelingen', 'percentage_succesvolle_betalingsregelingen', 'belastingheffing_uitbesteed', 'percentage_social_return', 'percentage_duurzaamheid_gunningscriterium', 'gemiddeld_wegingspercentage_duurzaamheidscriterium', 'verbetersuggesties_vragenlijst']
all_VVW_dt = ['int', 'int', 'float', 'text', 'text', 'text', 'text', 'text', 'text', 'text', 'float', 'int', 'float', 'int', 'float', 'float', 'float', 'float', 'int', 'int', 'int', 'int', 'float', 'float', 'float', 'float', 'float', 'int', 'int', 'int', 'int', 'float', 'float', 'float', 'float', 'float', 'float', 'float', 'float', 'float', 'float', 'float', 'float', 'float', 'float', 'float', 'float', 'float', 'float', 'float', 'float', 'float', 'int', 'float', 'float', 'float', 'float', 'float', 'float', 'float', 'float', 'float', 'float', 'float', 'float', 'float', 'int', 'float', 'float', 'int', 'float', 'float', 'float', 'float', 'float', 'float', 'float', 'float', 'text', 'float', 'float', 'float', 'text']

indices_to_remove = [46, 47, 48, 49, 50, 51, 52, 53, 54, 72, 73, 75, 78] # Null columns 

for index in sorted(indices_to_remove, reverse=True):
    del vvw_vragenlijst[index]

for index in sorted(indices_to_remove, reverse=True):
    del dataupd[index]

# Finding values in VVW_vragenlijst that are not in allvvw
missing_values = [item for item in vvw_vragenlijst if item not in all_VVW]

# Finding all indices of the target string
indices = [i for i, x in enumerate(vvw_vragenlijst) if x == 'null']
#print(f"All indices are: {indices}")


vvw2023mapping = dict(zip(dataupd,vvw_vragenlijst))

vvw2023mapping = {key: value for key, value in vvw2023mapping.items() if value != 'null'}

output_columns = ['VVW_id', 'naam_organisatie', 'formatieve_omvang_financien_toezicht_controle', 'formatieve_omvang', 'formatieve_omvang_leidinggevenden_hele_organisatie', 'formatieve_omvang_managementondersteuning_hele_organisatie', 'formatieve_omvang_bestuurszaken', 'werkelijke_bezetting', 'totaal_medewerkers', 'formatieve_omvang_leidinggevenden_bedrijfsvoering', 'formatieve_omvang_managementondersteuning_bedrijfsvoering', 'formatieve_omvang_p_o_hrm', 'formatieve_omvang_inkoopfunctie', 'formatieve_omvang_communicatiefunctie', 'formatieve_omvang_juridische_zaken', 'formatieve_omvang_ict', 'formatieve_omvang_facilitaire_zaken', 'aantal_fte_bepaalde_tijd', 'aantal_externe_inhuur_fte', 'aantal_externe_inhuur_personen', 'aantal_fte_salarisschaal_1_6', 'aantal_fte_salarisschaal_7_9', 'aantal_fte_salarisschaal_10_12', 'aantal_fte_salarisschaal_13_hoger', 'aantal_fte_salarisschaal_onbekend', 'uitgaven_opleiding_ontwikkeling', 'medewerkers_tot_35_jaar', 'medewerkers_35_45_jaar', 'medewerkers_45_55_jaar', 'medewerkers_55_ouder', 'medewerkers_in_dienst', 'medewerkers_vertrokken', 'dienstverband_korter_dan_3_jaar', 'dienstverband_10_jaar_of_langer', 'werkelijke_apparaatskosten', 'totale_loonsom', 'totale_ict_kosten', 'ict_kosten_personeelskosten', 'ict_kosten_inhuur_uitbesteding', 'ict_kosten_software', 'ict_kosten_hardware', 'ict_kosten_telefonie_datacommunicatie', 'ict_kosten_afschrijvingen', 'totale_ict_kosten_inclusief_procesautomatisering', 'totale_kosten_inhuur', 'percentage_tijdige_betalingen', 'kosten_heffing_waterschapsbelastingen', 'totaal_aanslagregels', 'kosten_invordering_waterschapsbelastingen', 'totaal_aanslagbiljetten', 'invorderingsopbrengsten', 'percentage_bezwaren_afgerond_6_weken', 'percentage_verzoekschriften_afgehandeld_8_weken', 'percentage_digitale_aanslagen', 'percentage_geinde_belasting_huidigemeting', 'percentage_geinde_belasting_vorigemeting', 'percentage_afgesloten_betalingsregelingen', 'percentage_succesvolle_betalingsregelingen', 'belastingheffing_uitbesteed', 'verhuurbaar_vloeroppervlak', 'beschikbare_werkplekken', 'percentage_duurzaamheid_gunningscriterium', 'gemiddeld_wegingspercentage_duurzaamheidscriterium', 'formatieve_omvang_datafuncties', 'totaal_exploitatierekening', 'kosten_inhuur_uitbesteding_overhead', 'formatieve_omvang_div', 'huisvestingskosten_kantoorruimte', 'percentage_e_facturen', 'betaaltermijn', 'percentage_social_return', 'verbetersuggesties_vragenlijst', 'percentage_ziekteverzuim', 'gemiddelde_meldingsfrequentie', 'year']
output_datatypes = []

output_datatypes = [
    'int',    # VVW_id
    'text',   # naam_organisatie
    'float',   # formatieve_omvang_financien_toezicht_controle
    'float',  # formatieve_omvang
    'float',  # formatieve_omvang_leidinggevenden_hele_organisatie
    'float',  # formatieve_omvang_managementondersteuning_hele_organisatie
    'float',  # formatieve_omvang_bestuurszaken
    'float',  # werkelijke_bezetting
    'int',  # totaal_medewerkers
    'float',  # formatieve_omvang_leidinggevenden_bedrijfsvoering
    'float',  # formatieve_omvang_managementondersteuning_bedrijfsvoering
    'float',  # formatieve_omvang_p_o_hrm
    'float',  # formatieve_omvang_inkoopfunctie
    'float',  # formatieve_omvang_communicatiefunctie
    'float',  # formatieve_omvang_juridische_zaken
    'float',  # formatieve_omvang_ict
    'float',  # formatieve_omvang_facilitaire_zaken
    'float',  # aantal_fte_bepaalde_tijd
    'float',  # aantal_externe_inhuur_fte
    'int',  # aantal_externe_inhuur_personen
    'float',  # aantal_fte_salarisschaal_1_6
    'float',  # aantal_fte_salarisschaal_7_9
    'float',  # aantal_fte_salarisschaal_10_12
    'float',  # aantal_fte_salarisschaal_13_hoger
    'float',  # aantal_fte_salarisschaal_onbekend
    'float',  # uitgaven_opleiding_ontwikkeling
    'int',  # medewerkers_tot_35_jaar
    'int',  # medewerkers_35_45_jaar
    'int',  # medewerkers_45_55_jaar
    'int',  # medewerkers_55_ouder
    'int',  # medewerkers_in_dienst
    'int',  # medewerkers_vertrokken
    'int',  # dienstverband_korter_dan_3_jaar
    'int',  # dienstverband_10_jaar_of_langer
    'float',  # werkelijke_apparaatskosten
    'float',  # totale_loonsom
    'float',  # totale_ict_kosten
    'float',  # ict_kosten_personeelskosten
    'float',  # ict_kosten_inhuur_uitbesteding
    'float',  # ict_kosten_software
    'float',  # ict_kosten_hardware
    'float',  # ict_kosten_telefonie_datacommunicatie
    'float',  # ict_kosten_afschrijvingen
    'float',  # totale_ict_kosten_inclusief_procesautomatisering
    'float',  # totale_kosten_inhuur
    'float',  # percentage_tijdige_betalingen
    'float',  # kosten_heffing_waterschapsbelastingen
    'int',  # totaal_aanslagregels
    'float',  # kosten_invordering_waterschapsbelastingen
    'int',  # totaal_aanslagbiljetten
    'float',  # invorderingsopbrengsten
    'float',  # percentage_bezwaren_afgerond_6_weken
    'float',  # percentage_verzoekschriften_afgehandeld_8_weken
    'float',  # percentage_digitale_aanslagen
    'float',  # percentage_geinde_belasting_huidigemeting
    'float',  # percentage_geinde_belasting_vorigemeting
    'float',  # percentage_afgesloten_betalingsregelingen
    'float',  # percentage_succesvolle_betalingsregelingen
    'text',   # belastingheffing_uitbesteed
    'float',  # verhuurbaar_vloeroppervlak
    'int',  # beschikbare_werkplekken
    'int',  # percentage_duurzaamheid_gunningscriterium
    'float',  # gemiddeld_wegingspercentage_duurzaamheidscriterium
    'float',  # formatieve_omvang_datafuncties
    'float',  # totaal_exploitatierekening
    'float',  # kosten_inhuur_uitbesteding_overhead
    'float',  # formatieve_omvang_div
    'float',  # huisvestingskosten_kantoorruimte
    'float',  # percentage_e_facturen
    'float',  # betaaltermijn
    'float',  # percentage_social_return
    'text',   # verbetersuggesties_vragenlijst
    'float',  # percentage_ziekteverzuim
    'float',  # gemiddelde_meldingsfrequentie
    'int'     # year
]

columnname_datatypes = dict(zip(output_columns, output_datatypes))

def convert_to_sqlalchemy_type(data_type):
    if "text" in data_type:
        return String()
    elif "float" in data_type:
        return Float()
    elif "int" in data_type:
        return Integer()
    else:
        raise ValueError(f"Unsupported data type: {data_type}")

# Apply the conversion function to the list
sqlalchemy_data_types = [convert_to_sqlalchemy_type(dt) for dt in all_VVW_dt]

export_dt_dict = dict(zip(all_VVW, sqlalchemy_data_types))
# Creating a connection with the database using SQLalchemy instead. !!! username/password solution? 
def create_connection():
    engine = sqlalchemy.create_engine(
        'mysql+pymysql://qvanderlinden:XEMFj9Y8ErKyyY6df2MK@dev.kurtosis.nl/venster_voor_waterschappen'
        )
    return engine

#############################################################################################

# Deleting all columns in VVB_vragenlijst that contain 2023, so they can be refreshed with (possibly updated) data from the data_upd table. 
def delete_existing_rows(engine, destination_table):
    with engine.begin() as conn:  # Use `begin()` to ensure the transaction is committed
        # Count rows with year = 2023 before deletion
        count_query = sqlalchemy.text(f"SELECT COUNT(*) FROM {destination_table} WHERE year = 2023")
        initial_count = conn.execute(count_query).scalar()
        
        if initial_count > 0:
            # Delete rows with year = 2023
            delete_query = sqlalchemy.text(f"DELETE FROM {destination_table} WHERE year = 2023")
            result = conn.execute(delete_query)
            
            # Commit is automatically handled with `begin()` context manager
            print(f"Deleted {result.rowcount} rows from {destination_table}.")
            
            # Count rows again after deletion to confirm
            final_count = conn.execute(count_query).scalar()
            print(f"Rows with year 2023 before deletion: {initial_count}")
            print(f"Rows with year 2023 after deletion: {final_count}")
        else:
            print("No rows with year 2023 found.")

#############################################################################################

# Importing all rows with specified columns from data_upd as a pandas dataframe. 
def import_data(engine, source_table, s_columns):
    columns_str = ', '.join(f"`{col}`" for col in s_columns)
    query = f"SELECT {columns_str} FROM {source_table}"
    df = pd.read_sql(query, engine)
    return df

#############################################################################################

def transform_data(df):
    df = df.rename(columns=vvw2023mapping)
    df['year'] = 2023


    # 'gemiddeld_wegingspercentage_duurzaamheidscriterium' remove the 10-25, 25-30, 20-30
    # taking the lowest values of criteriums that are values like: '20-30%' and ensure that split is only applied to non-None and string values
    df['gemiddeld_wegingspercentage_duurzaamheidscriterium'] = df['gemiddeld_wegingspercentage_duurzaamheidscriterium'].apply(lambda x: x.split('-')[0] if isinstance(x, str) else x)

    # Keeps only the lowest number before the dash
    df['percentage_duurzaamheid_gunningscriterium'] = df['percentage_duurzaamheid_gunningscriterium'].apply(lambda x: x.split('-')[0] if isinstance(x, str) else x)
    # Removes any characters that are not number 0-9 (\D regex detection)
    import re
    df['percentage_duurzaamheid_gunningscriterium'] = df['percentage_duurzaamheid_gunningscriterium'].apply(lambda x: re.sub(r'\D', '', x) if isinstance(x, str) else x)


    for key, value in columnname_datatypes.items():
        if value == 'float':
            # Replace commas with periods
            df[key] = df[key].astype(str).str.replace(',', '.', regex=False)
            # Replace 'None' and None with np.nan
            df[key] = df[key].replace({'None': np.nan, None: np.nan})
            # Convert to float
            df[key] = pd.to_numeric(df[key], errors='coerce').astype('float64')
    
    for key, value in columnname_datatypes.items():
        if value == 'int':
            # Replace commas with periods
            df[key] = df[key].astype(str).str.replace(',', '.', regex=False)
            # Replace 'None' and None with np.nan
            df[key] = df[key].replace({'None': np.nan, None: np.nan})
            # Convert to float
            df[key] = pd.to_numeric(df[key], errors='coerce').astype('Int64')

    

    columns_to_divide = [
    'percentage_social_return',
    'gemiddeld_wegingspercentage_duurzaamheidscriterium',
    'percentage_verzoekschriften_afgehandeld_8_weken',
    'percentage_ziekteverzuim',
    'percentage_digitale_aanslagen',
    'percentage_geinde_belasting_huidigemeting',
    'percentage_afgesloten_betalingsregelingen',
    'percentage_succesvolle_betalingsregelingen',
    'percentage_tijdige_betalingen'
    ]

    # Filter out columns that are not in the DataFrame
    columns_in_df = [col for col in columns_to_divide if col in df.columns]

    missing_columns = [col for col in columns_to_divide if col not in df.columns]

    # Divide the specified columns by 100 if they exist in the DataFrame
    df[columns_in_df] = df[columns_in_df].div(100)

    # Print the columns that are not in the DataFrame
    if missing_columns:
        print("The following columns are not in the DataFrame:", missing_columns)

    # Mapping van VVW_id to naam_organisatie
    id_to_organization = {
        4: 'ICTU - Testaccount Emma',
        5: 'ICTU - Testaccount Johan',
        9108: 'Waterschap De Dommel',
        9109: 'HH. Schieland Krimpenerwaard',
        9110: 'Hoogheemraadschap van Delfland',
        9111: 'Waterschap Rijn en IJssel',
        9112: 'Waterschap Scheldestromen',
        9114: 'Waterschap Brabantse Delta',
        9115: 'Waterschap Rivierenland',
        9116: 'Waterschap Zuiderzeeland',
        9570: 'Waterschap Aa en Maas',
        9572: 'Hoogheemraadschap van Rijnland',
        11385: 'Hoogheemraadschap Hollands Noorderkwartier',
        11387: 'Hoogheemraadschap Stichtse Rijnlanden',
        11389: 'Waterschap Hollandse Delta',
        11390: 'Waterschap Vechtstromen',
        11392: 'Waterschap Roer en Overmaas',
        11394: 'Wetterskip Fryslan',
        11395: 'Waterschap Peel en Maasvallei',
        11397: 'Waterschap Vallei en Veluwe',
        11398: 'Waterschap Noorderzijlvest',
        11399: 'Waterschap Hunze en Aa\'s',
        11400: 'Waterschap Limburg',
        11578: 'Waternet (AGV)',
        36533: 'Waterschap Drents Overijsselse Delta', 
        36534: 'ICTU - Testaccount Bastiaan'
    }
    df['naam_organisatie'] = df['VVW_id'].map(id_to_organization)

    #df['naam_organisatie'] = df.apply(
    #    lambda row: id_to_organization.get(row['VVW_id'], row['naam_organisatie']) 
    #                if pd.isna(row['naam_organisatie']) or row['naam_organisatie'] == '' else row['naam_organisatie'], 
    #    axis=1
    #)
    return df

#############################################################################################

def export_data(engine, df, table_name):
    try:
        df.to_sql(name=table_name, con=engine, 
                  if_exists='append', # If the table already exists, the new data is appended to the existing table. If the table does not exist, it is created.
                  index=False, # We do not include the row index
                  dtype=export_dt_dict # refers to a dictionary that maps the column name to the SQLalchemy datatypes.
                  )
        print("Data inserted successfully.")
    except SQLAlchemyError as err:
        print(f"Error inserting data: {err}")

#############################################################################################

# Main execution function 
def main():
    source_table = 'data_upd'
    destination_table = 'VVW_vragenlijst'

    engine = create_connection()

    try:
        delete_existing_rows(engine, destination_table)
        df = import_data(engine, source_table, dataupd)

        if not df.empty:
            df = transform_data(df)
            export_data(engine, df, destination_table)
            print("Data transformation and export completed successfully.")
        else:
            print("No new data to process.")
    finally:
        engine.dispose()


# boilerplate code
if __name__ == "__main__":    
    main()