Imed Riadh Farah

164 papers B 13C 28Misc 31Journal 63Unranked 29
YearRankTypeTitle / Venue / Authors
2026 J jnl
Expert Syst. Appl.
Mohamed Chahine Bouaziz, Ali Ben Abbes, Mourad El Koundi, Imed Riadh Farah
2026 conf
ICAART (3)
Rim Douss, Imed Riadh Farah
2026 J jnl
Int. J. Data Sci. Anal.
Mohamed Amine Ben Rhaiem, Mouna Selmi, Imed Riadh Farah, Amel Bouzeghoub
2026 J jnl
Appl. Soft Comput.
Mohamed Chahine Bouaziz, Mourad El Koundi, Ali Ben Abbes, Imed Riadh Farah
2025 conf
JURSE
Hanen Balti, Manel Rhif, Farah Chouikhi, Ali Ben Abbes, Mohamed Farah, Imed Riadh Farah
2025 J jnl
Environ. Model. Softw.
Farah Chouikhi, Ali Ben Abbes, Imed Riadh Farah
2025 conf
JURSE
Raja Inoubli, Lilia Bennaceur Farah, Imed Riadh Farah, Alejandro Monsiváis-Huertero
2025 conf
JURSE
Farah Chouikhi, Ali Ben Abbes, Manel Rhif, Imed Riadh Farah
2025 J jnl
Pattern Recognit. Lett.
Farah Chouikhi, Ali Ben Abbes, Imed Riadh Farah
2025 J jnl
Ecol. Informatics
Yosra Hajjaji, Wadii Boulila, Imed Riadh Farah, Anis Koubaa
2025 conf
AIAI (3)
Emna Klai, Ahmed Toujani, Manel Zaghdoudi, Wahbi Jaouadi, Imed Riadh Farah, Sami Faïz
2025 J jnl
Comput. Sci. Rev.
Dorsaf Sellami, Wissem Inoubli, Imed Riadh Farah, Sabeur Aridhi
2025 B conf
IEEE Big Data
Dorsaf Sellami, Wissem Inoubli, Imed Riadh Farah, Sabeur Aridhi
2025 B conf
ICTAI
Aya Ferchichi, Ali Ben Abbes, Vincent Barra, Imed Riadh Farah
2025 conf
JURSE
Mohamed Aymen Ben Khalifa, Mourad El Koundi, Imed Riadh Farah
2024 J jnl
Soft Comput.
Hanen Balti, Ali Ben Abbes, Imed Riadh Farah
2024 Misc conf
ATSIP
Refka Hanachi, Akrem Sellami, Imed Riadh Farah, Mauro Dalla Mura
2024 J jnl
Artif. Intell. Rev.
Ali Ben Abbes, Noureddine Jarray, Imed Riadh Farah
2024 J jnl
IEEE J. Sel. Top. Appl. Earth Obs. Remote. Sens.
Raja Inoubli, Daniel Enrique Constantino-Recillas, Alejandro Monsiváis-Huertero, Lilia Bennaceur Farah, Imed Riadh Farah
2024 Misc conf
ATSIP
Raja Inoubli, Daniel Enrique Constantino-Recillas, Alejandro Monsiváis-Huertero, Lilia Bennaceur Farah, Imed Riadh Farah
2024 B conf
KES
Manel Rhif, Ali Ben Abbes, Beatriz Martínez, Imed Riadh Farah
2024 B conf
KES
Manel Khazri Khelif, Wadii Boulila, Anis Koubaa, Imed Riadh Farah
2024 Misc conf
ATSIP
Mariem Ayad, Akrem Sellami, Imed Riadh Farah, Mauro Dalla Mura
2024 J jnl
Knowl. Based Syst.
Refka Hanachi, Akrem Sellami, Imed Riadh Farah, Mauro Dalla Mura
2024 C conf
IGARSS
Farah Chouikhi, Ali Ben Abbes, Imed Riadh Farah
2024 C conf
IGARSS
Azza Abidi, Dino Ienco, Ali Ben Abbes, Imed Riadh Farah
2024 J jnl
Eng. Appl. Artif. Intell.
Aya Ferchichi, Ali Ben Abbes, Vincent Barra, Manel Rhif, Imed Riadh Farah
2024 J jnl
Neural Comput. Appl.
Refka Hanachi, Akrem Sellami, Imed Riadh Farah, Mauro Dalla Mura
2024 J jnl
Neural Comput. Appl.
Azza Abidi, Dino Ienco, Ali Ben Abbes, Imed Riadh Farah
2024 C conf
IGARSS
Raja Inoubli, Daniel Enrique Constantino-Recillas, Alejandro Monsiváis-Huertero, Lilia Bennaceur Farah, Imed Riadh Farah
2024 Misc conf
ATSIP
Farah Chouikhi, Ali Ben Abbes, Imed Riadh Farah
2023 J jnl
Remote. Sens.
Abir Bousmina, Mouna Selmi, Mohamed Amine Ben Rhaiem, Imed Riadh Farah
2023 J jnl
Eng. Appl. Artif. Intell.
Azza Abidi, Dino Ienco, Ali Ben Abbes, Imed Riadh Farah
2023 J jnl
Earth Sci. Informatics
Ali Ben Abbes, Raja Inoubli, Manel Rhif, Imed Riadh Farah
2023 B conf
ICCCI
Refka Hanachi, Akrem Sellami, Imed Riadh Farah, Mauro Dalla Mura
2023 B conf
ICCCI
Farah Chouikhi, Ali Ben Abbes, Imed Riadh Farah
2023 C conf
IGARSS
Raja Inoubli, Daniel Enrique Constantino-Recillas, Alejandro Monsiváis-Huertero, Lilia Bennaceur Farah, Imed Riadh Farah
2023 J jnl
Comput. Sci. Rev.
Manel Khazri Khlifi, Wadii Boulila, Imed Riadh Farah
2023 conf
IntelliSys (2)
Mohamed Louay Rabah, Nedra Mellouli, Imed Riadh Farah
2023 J jnl
Artif. Intell. Rev.
Noureddine Jarray, Ali Ben Abbes, Imed Riadh Farah
2023 J jnl
CoRR
Zouhayra Ayadi, Wadii Boulila, Imed Riadh Farah
2023 B conf
KES
Zouhayra Ayadi, Wadii Boulila, Imed Riadh Farah
2023 J jnl
Comput. Geosci.
Hanen Balti, Ali Ben Abbes, Yan-Fang Sang, Nedra Mellouli, Imed Riadh Farah
2023 B conf
KES
Yosra Hajjaji, Ayyub Alzahem, Wadii Boulila, Imed Riadh Farah, Anis Koubaa
2023 J jnl
CoRR
Yosra Hajjaji, Ayyub Alzahem, Wadii Boulila, Imed Riadh Farah, Anis Koubaa
2023 J jnl
Appl. Soft Comput.
Manel Rhif, Ali Ben Abbes, Beatriz Martínez, Imed Riadh Farah
2022 J jnl
Remote. Sens.
Wadii Boulila, Manel Khazri Khlifi, Adel Ammar, Anis Koubaa, Bilel Benjdira, Imed Riadh Farah
2022 conf
ISDA (2)
Noureddine Jarray, Ali Ben Abbes, Imed Riadh Farah
2022 J jnl
IEEE Geosci. Remote. Sens. Lett.
Noureddine Jarray, Ali Ben Abbes, Imed Riadh Farah
2022 Misc conf
ATSIP
Mariem Ayed, Refka Hanachi, Akrem Sellami, Imed Riadh Farah, Mauro Dalla Mura
2022 conf
BELIEF
Manel Chehibi, Ahlem Ferchichi, Imed Riadh Farah
2022 C conf
IGARSS
Farah Chouikhi, Manel Rhif, Ali Ben Abbes, Imed Riadh Farah
2022 J jnl
Ecol. Informatics
Manel Rhif, Ali Ben Abbes, Beatriz Martínez, Rogier de Jong, Yan-Fang Sang, Imed Riadh Farah
2022 J jnl
Ecol. Informatics
Aya Ferchichi, Ali Ben Abbes, Vincent Barra, Imed Riadh Farah
2022 J jnl
Remote. Sens.
Slim Namouchi, Imed Riadh Farah
2022 Misc conf
ATSIP
Wissal Ben Marzouka, Basel Solaiman, Mohamed Farah, Imed Riadh Farah
2022 B conf
KES
Yosra Hajjaji, Wadii Boulila, Imed Riadh Farah
2022 J jnl
CoRR
Yosra Hajjaji, Wadii Boulila, Imed Riadh Farah
2022 Misc conf
ATSIP
Imen Gatfaoui, Basel Solaiman, Imed Riadh Farah
2022 conf
EGC
Mohamed Louay Rabah, Nedra Mellouli, Imed Riadh Farah
2022 conf
WHISPERS
Refka Hanachi, Akrem Sellami, Imed Riadh Farah, Mauro Dalla Mura
2022 J jnl
Future Gener. Comput. Syst.
Hanen Balti, Ali Ben Abbes, Nedra Mellouli, Imed Riadh Farah, Yan-Fang Sang, Myriam Lamolle
2022 C conf
IGARSS
Oumayma Bounouh, Ana Maria Tarquis, Imed Riadh Farah
2022 J jnl
Expert Syst. Appl.
Manel Chehibi, Ahlem Ferchichi, Imed Riadh Farah
2022 J jnl
Ecol. Informatics
Zouhayra Ayadi, Wadii Boulila, Imed Riadh Farah, Aurélie Leborgne, Pierre Gançarski
2022 J jnl
Environ. Model. Softw.
Noureddine Jarray, Ali Ben Abbes, Manel Rhif, Hanen Dhaou, Mohamed Ouessar, Imed Riadh Farah
2022 C conf
IGARSS
Hanen Balti, Manel Rhif, Farah Chouikhi, Raja Inoubli, Azza Abidi, Noureddine Jarray, Ali Ben Abbes, Imed Riadh Farah
2022 Misc conf
ATSIP
Ikram Chourib, Gwenaël Guillard, Imed Riadh Farah, Basel Solaiman
2022 conf
EAIS
Nedra Mellouli, Mohamed Louay Rabah, Imed Riadh Farah
2021 B conf
KES
Zouhayra Ayadi, Wadii Boulila, Imed Riadh Farah
2021 J jnl
CoRR
Zouhayra Ayadi, Wadii Boulila, Imed Riadh Farah
2021 C conf
IGARSS
Noureddine Jarray, Ali Ben Abbes, Imed Riadh Farah
2021 B conf
ICCCI
Manel Rhif, Ali Ben Abbes, Beatriz Martínez, Imed Riadh Farah
2021 B conf
KES
Yosra Hajjaji, Wadii Boulila, Imed Riadh Farah
2021 J jnl
CoRR
Yosra Hajjaji, Wadii Boulila, Imed Riadh Farah
2021 conf
VISIGRAPP (Revised Selected Papers)
Refka Hanachi, Akrem Sellami, Imed Riadh Farah
2021 J jnl
Big Data Cogn. Comput.
Imen Chebbi, Nedra Mellouli, Imed Riadh Farah, Myriam Lamolle
2021 J jnl
Comput. Sci. Rev.
Yosra Hajjaji, Wadii Boulila, Imed Riadh Farah, Imed Romdhani, Amir Hussain
2021 conf
ISD
Hanen Balti, Nedra Mellouli, Ali Ben Abbes, Imed Riadh Farah, Yangfan Sang, Myriam Lamolle
2021 conf
VISIGRAPP (4: VISAPP)
Refka Hanachi, Akrem Sellami, Imed Riadh Farah
2021 J jnl
Remote. Sens.
Bouthayna Msellmi, Daniele Picone, Zouhaier Ben Rabah, Mauro Dalla Mura, Imed Riadh Farah
2020 Misc conf
ATSIP
Raja Inoubli, Ali Ben Abbes, Imed Riadh Farah, Vijay Singh, Tsegaye Tadesse, Mohammad Taghi Sattari
2020 J jnl
Ecol. Informatics
Hanen Balti, Ali Ben Abbes, Nedra Mellouli, Imed Riadh Farah, Yan-Fang Sang, Myriam Lamolle
2020 Misc conf
ATSIP
Ikram Chourib, Gwenaël Guillard, Makram Mestiri, Basel Solaiman, Imed Riadh Farah
2020 J jnl
Pattern Recognit. Lett.
Akrem Sellami, Ali Ben Abbes, Vincent Barra, Imed Riadh Farah
2020 Misc conf
ATSIP
Salim Klibi, Kais Tounsi, Zouhaier Ben Rabah, Basel Solaiman, Imed Riadh Farah
2020 C conf
IGARSS
Bouthayna Msellmi, Daniele Picone, Zouhaier Ben Rabah, Mauro Dalla Mura, Imed Riadh Farah
2020 Misc conf
ATSIP
Bouthayna Msellmi, Daniele Picone, Zouhaier Ben Rabah, Mauro Dalla Mura, Imed Riadh Farah
2020 Misc conf
ATSIP
Marwen Bouabid, Mohamed Farah, Imed Riadh Farah
2019 J jnl
IEEE Trans. Geosci. Remote. Sens.
Fethi Ghazouani, Imed Riadh Farah, Basel Solaiman
2019 J jnl
Int. J. Inf. Decis. Sci.
Ali Ben Abbes, Mohamed Farah, Imed Riadh Farah, Vincent Barra
2019 conf
KDIR
Imen Chebbi, Nedra Mellouli, Myriam Lamolle, Imed Riadh Farah
2019 conf
KDIR
Hanen Balti, Nedra Mellouli, Imen Chebbi, Imed Riadh Farah, Myriam Lamolle
2019 J jnl
Int. J. Uncertain. Fuzziness Knowl. Based Syst.
Wassim Messaoudi, Mohamed Farah, Imed Riadh Farah
2019 J jnl
Expert Syst. Appl.
Akrem Sellami, Mohamed Farah, Imed Riadh Farah, Basel Solaiman
2019 C conf
IGARSS
Bouthayna Msellmi, Daniele Picone, Mauro Dalla Mura, Zouhaier Ben Rabah, Imed Riadh Farah
2019 C conf
IGARSS
Slim Namouchi, Bruno Vallet, Imed Riadh Farah, Haythem Ismail
2019 J jnl
IEEE Geosci. Remote. Sens. Lett.
Yaakoub Boualleg, Mohamed Farah, Imed Riadh Farah
2018 C conf
IGARSS
Bouthayna Msellmi, Zouhaier Ben Rabah, Imed Riadh Farah
2018 Misc conf
ATSIP
Imen Chebbi, Wadii Boulila, Nedra Mellouli, Myriam Lamolle, Imed Riadh Farah
2018 J jnl
Earth Sci. Informatics
Wadii Boulila, Imed Riadh Farah, Amir Hussain
2018 B conf
ICPR
Manel Rhif, Hazem Wannous, Imed Riadh Farah
2018 Misc conf
ATSIP
Rawaa Hamdi, Akrem Sellami, Imed Riadh Farah
2018 J jnl
Ecol. Informatics
Ahlem Ferchichi, Wadii Boulila, Imed Riadh Farah
2018 conf
IEEE Conf. on Intelligent Systems
Khadhar Meriem, Makram Mestiri, Imed Riadh Farah
2018 J jnl
IEEE J. Sel. Top. Appl. Earth Obs. Remote. Sens.
Akrem Sellami, Mohamed Farah, Imed Riadh Farah, Basel Solaiman
2018 J jnl
IEEE J. Sel. Top. Appl. Earth Obs. Remote. Sens.
Ines Ben Slimene Ben Amor, Nesrine Chehata, Jean-Stéphane Bailly, Imed Riadh Farah, Philippe Lagacherie
2018 Misc conf
ATSIP
Yosra Hajjaji, Imed Riadh Farah
2018 Misc conf
ATSIP
Fethi Ghazouani, Imed Riadh Farah, Basel Solaiman
2018 J jnl
Knowl. Inf. Syst.
Ahlem Ferchichi, Wadii Boulila, Imed Riadh Farah
2018 conf
IEEE Conf. on Intelligent Systems
Khadhar Meriem, Makram Mestiri, Imed Riadh Farah
2017 Misc conf
ATSIP
Khitem Amiri, Mohamed Farah, Imed Riadh Farah
2017 Misc conf
ATSIP
Oumayma Bounouh, Houcine Essid, Imed Riadh Farah
2017 J jnl
Ecol. Informatics
Ahlem Ferchichi, Wadii Boulila, Imed Riadh Farah
2017 Misc conf
ATSIP
Malek Boujebli, Hassen Drira, Makram Mestiri, Imed Riadh Farah
2017 J jnl
J. Comput. Sci.
Wadii Boulila, Zouhayra Ayadi, Imed Riadh Farah
2017 J jnl
Vietnam. J. Comput. Sci.
Ahlem Ferchichi, Wadii Boulila, Imed Riadh Farah
2016 J jnl
Comput. Geosci.
Mohamed Farah, Hafed Nefzi, Imed Riadh Farah
2016 Misc conf
ATSIP
Zouhaier Ben Rabah, Imed Riadh Farah
2016 Misc conf
ATSIP
Mohamed Farah, Khitem Amiri, Imed Riadh Farah
2016 Misc conf
ATSIP
Imen Chebbi, Wadii Boulila, Imed Riadh Farah
2016 Misc conf
ATSIP
Ibtissem Hosni, Lilia Bennaceur Farah, Saber Mohamed Naceur, Imed Riadh Farah
2016 Misc conf
ATSIP
Zouhayra Ayadi, Wadii Boulila, Imed Riadh Farah
2016 Misc conf
ATSIP
Bouthayna Msellmi, Zouhaier Ben Rabah, Imed Riadh Farah
2016 Misc conf
ATSIP
Fethi Ghazouani, Wassim Messaoudi, Imed Riadh Farah
2015 C conf
KEOD
Fethi Ghazouani, Wassim Messaoudi, Imed Riadh Farah
2015 conf
ICCCI (2)
Ahlem Ferchichi, Wadii Boulila, Imed Riadh Farah
2015 conf
SAGEO
Fedia Ghedass, Imed Riadh Farah
2015 conf
ICCCI (2)
Imen Chebbi, Wadii Boulila, Imed Riadh Farah
2015 C conf
IGARSS
Ines Ben Slimene Ben Amor, Nesrine Chehata, Philippe Lagacherie, Jean-Stéphane Bailly, Imed Riadh Farah
2015 conf
IJCCI (Selected Papers)
Ahlem Ferchichi, Wadii Boulila, Imed Riadh Farah
2015 C conf
IGARSS
Ali Ben Abbes, Houcine Essid, Imed Riadh Farah, Vincent Barra
2015 conf
IJCCI (FCTA)
Ahlem Ferchichi, Wadii Boulila, Imed Riadh Farah
2014 J jnl
J. Multim. Process. Technol.
Wadii Boulila, Amine Bouatay, Imed Riadh Farah
2014 C conf
KEOD
Hafed Nefzi, Mohamed Farah, Imed Riadh Farah, Basel Solaiman
2014 Misc conf
ATSIP
Hafed Nefzi, Mohamed Farah, Imed Riadh Farah, Basel Solaiman
2014 Misc conf
ATSIP
Wassim Messaoudi, Imed Riadh Farah, Basel Solaiman
2014 Misc conf
ATSIP
Ali Ben Abbes, Houcine Essid, Imed Riadh Farah, Vincent Barra
2014 conf
ICAISC (1)
Amine Bouatay, Wadii Boulila, Imed Riadh Farah
2014 C conf
IPAS
Ali Ben Abbes, Houcine Essid, Imed Riadh Farah, Vincent Barra
2014 C conf
IPAS
Akrem Sellami, Karim Saheb Ettabaâ, Imed Riadh Farah, Basel Solaiman
2014 C conf
IPAS
B. Mselmi, Zouhaier Ben Rabah, Imed Riadh Farah, Basel Solaiman
2014 C conf
IPAS
Ahlem Ferchichi, Wadii Boulila, Imed Riadh Farah
2014 C conf
IPAS
Hafedh Nefzi, Mohamed Farah, Imed Riadh Farah, Basel Solaiman
2014 C conf
IPAS
Ines Ben Slimene Ben Amor, Nesrine Chehata, Imed Riadh Farah, Philippe Lagacherie
2013 C conf
ICPRAM
Selim Hemissi, Imed Riadh Farah
2013 conf
WHISPERS
Selim Hemissi, Imed Riadh Farah
2013 conf
KDIR/KMIS
Ahlem Ferchichi, Wadii Boulila, Imed Riadh Farah
2013 J jnl
IEEE Trans. Geosci. Remote. Sens.
Selim Hemissi, Imed Riadh Farah, Karim Saheb Ettabaâ, Basel Solaiman
2012 C conf
IGARSS
Selim Hemissi, Imed Riadh Farah, Karim Saheb Ettabaâ, Basel Solaiman
2012 Misc conf
SAC
Wadii Boulila, Karim Saheb Ettabaâ, Imed Riadh Farah, Basel Solaiman
2011 J jnl
IEEE Geosci. Remote. Sens. Lett.
Zouhaier Ben Rabah, Imed Riadh Farah, Grégoire Mercier, Basel Solaiman
2011 J jnl
Int. J. Appl. Earth Obs. Geoinformation
Wadii Boulila, Imed Riadh Farah, Karim Saheb Ettabaâ, Basel Solaiman, Henda Ben Ghézala
2011 J jnl
J. Multim. Process. Technol.
Wadii Boulila, Imed Riadh Farah, Karim Saheb Ettabaâ, Basel Solaiman
2011 J jnl
Int. J. Image Graph.
Wadii Boulila, Imed Riadh Farah
2010 conf
CORIA
Wadii Boulila, Imed Riadh Farah, Karim Saheb Ettabaâ, Basel Solaiman, Henda Ben Ghézala
2008 J jnl
IEEE Trans. Geosci. Remote. Sens.
Imed Riadh Farah, Wadii Boulila, Karim Saheb Ettabaâ, Basel Solaiman, Mohamed Ben Ahmed
2008 J jnl
IEEE Trans. Geosci. Remote. Sens.
Imed Riadh Farah, Wadii Boulila, Karim Saheb Ettabaâ, Mohamed Ben Ahmed
2008 J jnl
Int. Arab J. Inf. Technol.
Karim Saheb Ettabaâ, Imed Riadh Farah, Soulaimen Basel, Mohamed Ben Ahmed
2007 conf
BIOCOMP
Ines Hamdi, Imed Riadh Farah, Mohamed Ben Ahmed
2007 C conf
IGARSS
Karim Saheb Ettabaâ, Imed Riadh Farah, Mohamed Ben Ahmed, Soulaiman Bassel
2005 C conf
AICCSA
Ines Hamdi, Imed Riadh Farah, Mohmed B. Ahmed
2003 C conf
IGARSS
Imed Riadh Farah, Mohamed Ben Ahmed, Mohamed Rached Boussema
2002 C conf
IGARSS
Imed Riadh Farah, Mohamed Ben Ahmed
redb/extractors/database_exporters.py
← Index redb/extractors/database_exporters.py python
from abc import ABC, abstractmethod
from datetime import datetime, timezone
from dataclasses import asdict
import hashlib
import json
import inspect
from typing import Any, Dict, List, Union
from redb import settings
import traceback
from contextlib import contextmanager

class DatabaseExporter(ABC):
    @abstractmethod
    def export(self, data: Any, **kwargs) -> bool:
        """Export data to the database"""
        pass

class ElasticsearchExporter(DatabaseExporter):
    def __init__(self, logger: Any, index_prefix: str):
        self.client = settings.get_elasticsearch_client()
        self.index_prefix = index_prefix
        self.log = logger

    def export(self, data: Any, **kwargs) -> bool:
        self.log.debug(inspect.currentframe().f_code.co_name)
        if not isinstance(data, list):
            data = [data]
            
        now_t = datetime.now(timezone.utc).strftime("%Y-%m-%d %H:%M:%S")
        index = kwargs.get('index')
        tag = kwargs.get('tag')
        hashes = kwargs.get('hashes')
        
        for dataclass_ in data:
            try:
                # Convert dataclass to dict and filter out None values
                document = {k: v for k, v in asdict(dataclass_).items() if v is not None}
                
                if tag:
                    document["tag"] = tag
                document |= hashes
                document["timestamp_utc"] = now_t
                document["known_benign"] = kwargs.get('known_benign', False)
                document["known_malicious"] = kwargs.get('known_malicious', False)

                if "_id" in document:
                    tmp_id = document.pop("_id") + document["sha256"]
                    _id = hashlib.sha256(tmp_id.encode()).hexdigest()
                else:
                    _id = document["sha256"]

                doc_dump = json.dumps(document)
                self.client.index(index=index, id=_id, document=doc_dump)
                
            except Exception as e:
                self.log.error(f"Failed to export to Elasticsearch: {e}")
                return False
                
        return True

class PrintExporter(DatabaseExporter):
    """Exporter that prints results instead of uploading to database (for dry-run mode)"""
    def __init__(self, logger: Any, index_prefix: str):
        self.index_prefix = index_prefix
        self.log = logger
        self.log.debug(f"PrintExporter initialized with index_prefix: {index_prefix}")

    def export(self, data: Any, **kwargs) -> bool:
        try:
            import json
            from dataclasses import asdict, is_dataclass

            self.log.debug(f"PrintExporter.export called with data type: {type(data)}")

            if data is None:
                self.log.debug("PrintExporter.export: data is None, returning True")
                return True

            if not isinstance(data, list):
                data = [data]

            for i, item in enumerate(data):
                if is_dataclass(item) and not isinstance(item, type):
                    # Convert dataclass instance to dict
                    try:
                        item_dict = asdict(item)
                        print(json.dumps(item_dict, indent=2, default=str))
                    except Exception as e:
                        self.log.error(f"PrintExporter.export: Error converting dataclass: {e}")
                        print(str(item))
                elif isinstance(item, dict):
                    # Already a dict, print as JSON
                    print(json.dumps(item, indent=2, default=str))
                else:
                    # Fallback for other types
                    print(json.dumps(item, indent=2, default=str) if not isinstance(item, str) else item)

            self.log.debug("PrintExporter.export: completed successfully")
            return True
        except Exception as e:
            self.log.error(f"PrintExporter.export: Failed to print data: {e}")
            return False


class ClickHouseExporter(DatabaseExporter):
    def __init__(self, logger: Any, index_prefix: str, client=None):
        self.index_prefix = index_prefix
        self.log = logger
        self.client = client

    @contextmanager
    def clickhouse_connection(self):
        client = settings.create_clickhouse_client()
        try:
            yield client
        finally:
            try:
                client.close()
            except:
                pass
    # def export(self, data: Any, **kwargs) -> bool:
    #     try:
    #         # Handle multi-table export case
    #         # if isinstance(data, dict) and 'multi_table' in data:
    #         #     for table_name, table_data in data.items():
    #         #         if table_name != 'multi_table' and isinstance(table_data, dict) and 'table' in table_data:
    #         #             self.log.debug(f"Exporting to table: {table_data['table']}")
    #         #             self.log.debug(f"Column names: {table_data['column_names']}")
    #         #             self.log.debug(f"Column types: {table_data['column_type_names']}")
    #         #             self.log.debug(f"Data sample: {table_data['data'][0] if table_data['data'] else 'No data'}")
                        
    #         #             try:
    #         #                 result = self.client.insert(
    #         #                     table_data['table'],
    #         #                     table_data['data'],
    #         #                     column_names=table_data['column_names'],
    #         #                     column_type_names=table_data['column_type_names']
    #         #                 )
    #         #                 if not result:
    #         #                     self.log.error(f"Failed to insert into table {table_data['table']}")
    #         #                     return False
    #         #             except Exception as e:
    #         #                 self.log.error(f"Error inserting into table {table_data['table']}: {e}")
    #         #                 self.log.error(f"Data that caused error: {table_data['data']}")
    #         #                 return False
    #         #     return True

    #         if isinstance(data, dict) and 'multi_table' in data:
    #             for table_name, table_data in data.items():
    #                 if table_name != 'multi_table' and isinstance(table_data, dict) and 'table' in table_data:
    #                     self.log.debug(f"Exporting to table: {table_data['table']}")
                        
    #                     # Validate each row before insert
    #                     for row in table_data['data']:
    #                         for val, col_name, col_type in zip(row, table_data['column_names'], 
    #                                                         table_data['column_type_names']):
    #                             # Check for empty strings
    #                             if isinstance(val, str) and not val:
    #                                 self.log.error(f"Empty string found for column {col_name}")
    #                                 raise ValueError(f"Empty string not allowed for column {col_name}")
                                
    #                             # Log all string values for certificate_serial_number
    #                             if col_name == 'certificate_serial_number':
    #                                 self.log.debug(f"Serial number value: '{val}', type: {type(val)}, "
    #                                             f"repr: {repr(val)}")
                        
    #                     try:
    #                         result = self.client.insert(
    #                             table_data['table'],
    #                             table_data['data'],
    #                             column_names=table_data['column_names'],
    #                             column_type_names=table_data['column_type_names']
    #                         )
    #                         if not result:
    #                             self.log.error(f"Failed to insert into table {table_data['table']}")
    #                             return False
    #                     except Exception as e:
    #                         self.log.error(f"Error inserting into table {table_data['table']}: {e}")
    #                         self.log.error(f"Data that caused error: {table_data['data']}")
    #                         return False
    #             return True

    #         # Handle single table case
    #         table = kwargs.get('table')
    #         if not table:
    #             raise ValueError("Table name must be provided for ClickHouse export")
            
    #         # Unpack the tuple returned by prepare_export_data
    #         if isinstance(data, tuple):
    #             if len(data) != 3:
    #                 raise ValueError("Data tuple must contain exactly 3 elements: (data, column_names, column_type_names)")
    #             insert_data, column_names, column_type_names = data
    #         else:
    #             # Use provided column names and types from kwargs
    #             insert_data = data
    #             column_names = kwargs.get('column_names')
    #             column_type_names = kwargs.get('column_type_names')
                
    #         if not (column_names and column_type_names):
    #             raise ValueError("column_names and column_type_names must be provided")

    #         # Ensure data is in list format for batch insert
    #         if not isinstance(insert_data, list):
    #             insert_data = [insert_data]
                
    #         self.client.insert(
    #             table,
    #             insert_data,
    #             column_names=column_names,
    #             column_type_names=column_type_names
    #         )
    #         return True
            
    #     except Exception as e:
    #         self.log.error(f"Failed to export to ClickHouse: {e}")
    #         return False

    def get_client(self):
        """Get existing client or create new one if needed"""
        if self.client:
            return self.client
        try:
            return settings.create_clickhouse_client() 
        except Exception as e:
            self.log.error(f"Failed to create ClickHouse client: {e}")
            return None
            
    # WORKING SIMPLE VERSION
    def export(self, data: Any, **kwargs) -> bool:
        try:
            # # Handle multi-table export case
            # # if isinstance(data, dict) and 'multi_table' in data:
            # #     for table_data in data.values():
            # #         if isinstance(table_data, dict) and 'table' in table_data:
            # #             result = self.client.insert(
            # #                 table_data['table'],
            # #                 table_data['data'],
            # #                 column_names=table_data['column_names'],
            # #                 column_type_names=table_data['column_type_names']
            # #             )
            # #             if not result:  # If any insert fails, return False
            # #                 return False
            # #     return True
            # if isinstance(data, dict) and 'multi_table' in data:
            #     for key, table_data in data.items():
            #         if key != 'multi_table' and isinstance(table_data, dict) and 'table' in table_data:
            #             # Add type hints
            #             typed_data = []
            #             for row in table_data['data']:
            #                 typed_row = []
            #                 for val, type_name in zip(row, table_data['column_type_names']):
            #                     if isinstance(val, str) and not val:
            #                         val = 'UNKNOWN'
            #                     if type_name == 'String' or 'LowCardinality(String)' in type_name:
            #                         val = str(val) if val is not None else 'UNKNOWN'
            #                     typed_row.append(val)
            #                 typed_data.append(typed_row)
                        
            #             table_data['data'] = typed_data
                        
            #             result = self.client.insert(
            #                 table_data['table'],
            #                 table_data['data'],
            #                 column_names=table_data['column_names'],
            #                 column_type_names=table_data['column_type_names'],
            #                 settings={'input_format_values_interpret_expressions': 0}  # Disable type inference
            #             )
            #             if not result:
            #                 return False
            #         return True

            # Get a new client connection for this export operation
            with self.clickhouse_connection() as client:
                if not client:
                    return False

                # LAST WORKING VERSION
                if isinstance(data, dict) and 'multi_table' in data:
                    for key, table_data in data.items():
                        if key != 'multi_table' and isinstance(table_data, dict) and 'table' in table_data:
                            # Debug logging
                            self.log.debug(f"Processing table: {table_data['table']}")
                            self.log.debug(f"Column names: {table_data['column_names']}")
                            self.log.debug(f"Column types: {table_data['column_type_names']}")
                            
                            typed_data = []
                            for row_idx, row in enumerate(table_data['data']):
                                typed_row = []
                                for val_idx, (val, type_name, col_name) in enumerate(
                                    zip(row, table_data['column_type_names'], table_data['column_names'])
                                ):
                                    try:
                                        # Handle different types
                                        if val is None:
                                            if 'Nullable' in type_name:
                                                val = None  # Keep None for Nullable columns
                                            elif 'Array' in type_name:
                                                val = []
                                            elif 'Int' in type_name or 'UInt' in type_name:
                                                val = 0
                                            elif 'FixedString(16)' in type_name:
                                                val = b'\x00' * 16  # Binary FixedString
                                            elif 'String' in type_name or 'LowCardinality' in type_name:
                                                val = 'UNKNOWN'
                                            elif 'DateTime' in type_name:
                                                val = datetime.now(timezone.utc)
                                            elif 'Boolean' in type_name:
                                                val = False
                                            else:
                                                self.log.error(f"Unhandled type {type_name} for null value")
                                                val = 'UNKNOWN'
                                        
                                        # Log problematic values
                                        if isinstance(val, str) and not val.strip():
                                            self.log.warning(f"Empty string found in table {table_data['table']}, "
                                                        f"column {col_name}, row {row_idx}")
                                        
                                        # Ensure array types are always lists
                                        if 'Array' in type_name and not isinstance(val, list):
                                            val = [val]
                                        
                                        typed_row.append(val)
                                    except Exception as e:
                                        self.log.error(f"Error processing value in table {table_data['table']}, "
                                                    f"column {col_name} ({type_name}), "
                                                    f"row {row_idx}, value: {repr(val)}")
                                        raise
                                        
                                typed_data.append(typed_row)
                            
                            table_data['data'] = typed_data

                            # Skip insert if there is nothing to insert
                            if not typed_data:
                                self.log.debug(f"No data to insert for table {table_data['table']}, skipping.")
                                continue

                            # Debug log the first row of data
                            self.log.debug(f"Sample row for {table_data['table']}: {typed_data[0]}")

                            result = client.insert(
                                table_data['table'],
                                table_data['data'],
                                column_names=table_data['column_names'],
                                column_type_names=table_data['column_type_names'],
                                settings={'input_format_values_interpret_expressions': 0}
                            )
                            if not result:
                                self.log.error(f"Insert failed for table {table_data['table']}")
                                return False
                    return True

                # Handle single table case
                table = kwargs.get('table')
                if not table:
                    raise ValueError("Table name must be provided for ClickHouse export")
                
                # Unpack the tuple returned by prepare_export_data
                if isinstance(data, tuple):
                    if len(data) != 3:
                        raise ValueError("Data tuple must contain exactly 3 elements: (data, column_names, column_type_names)")
                    insert_data, column_names, column_type_names = data
                else:
                    # Use provided column names and types from kwargs
                    insert_data = data
                    column_names = kwargs.get('column_names')
                    column_type_names = kwargs.get('column_type_names')
                    
                if not (column_names and column_type_names):
                    raise ValueError("column_names and column_type_names must be provided")

                # Ensure data is in list format for batch insert
                if not isinstance(insert_data, list):
                    insert_data = [insert_data]

                # Skip insert if there is nothing to insert
                if not insert_data:
                    self.log.debug(f"No data to insert for table {table}, skipping.")
                    return True

                client.insert(
                    table,
                    insert_data,
                    column_names=column_names,
                    column_type_names=column_type_names,
                    settings={'input_format_values_interpret_expressions': 0}  # Disable type inference
                )
                return True

        except TypeError as e:
            # Get the actual value causing the error from the exception traceback
            import sys
            exc_type, exc_value, exc_traceback = sys.exc_info()
            
            # Walk through the traceback to find the frame with the problematic value
            current = exc_traceback
            while current:
                if 'string.py' in current.tb_frame.f_code.co_filename and '_data_size' in current.tb_frame.f_code.co_name:
                    locals_dict = current.tb_frame.f_locals
                    problematic_value = locals_dict.get('x')
                    self.log.error(f"TypeError with value: {problematic_value} (type: {type(problematic_value)})")
                    self.log.error(f"Full locals at error: {locals_dict}")
                    break
                current = current.tb_next
            
            self.log.error(f"Failed to export to ClickHouse: {e}")
            self.log.error("Full traceback:")
            self.log.error(traceback.format_exc())
            return False
        except Exception as e:
            self.log.error(f"Failed to export to ClickHouse: {e}")
            self.log.error(traceback.format_exc())
            return False
        finally:
            # Only close if we created a new client
            if client and client != self.client:
                # Close the client connection
                try:
                    client.close()
                except:
                    pass