Carlos Montez

87 papers B 2C 40Misc 1Journal 26Unranked 18
YearRankTypeTitle / Venue / Authors
2025 C conf
ETFA
Ivan Lehmkuhl, Carlos Montez, Ricardo de Moraes, Hector Leon, Paulo Portugal
2024 J jnl
Internet Things
Miguel Lino Ferreira Neto, Carlos Montez, Érico Leão, Ricardo J. Rabelo, Angelus Fayran, Francisco Vasques
2024 conf
WF-IoT
Juan David Arias Correa, Alex Sandro Roschildt Pinto, Carlos Montez
2023 J jnl
Ad Hoc Networks
Claudio Piccolo Fernandes, Carlos Montez, Daniel D. Adriano, Azzedine Boukerche, Michelle S. Wangham
2023 J jnl
IEEE Access
Ray Neiheiser, Gustavo Inácio, Luciana Rech, Carlos Montez, Miguel Matos, Luís E. T. Rodrigues
2022 C conf
INDIN
Vitor Vasconcelos, Érico Leão, Natanael Ribeiro, Francisco Vasques, Carlos Montez
2022 J jnl
IEEE Access
Guilherme Pereira, Suelen Laurindo, Gerson F. Budke, Carlos Montez, Ricardo de Moraes
2022 C conf
INDIN
Miguel Lino, Carlos Montez, Érico Leão, Ricardo Lira
2022 J jnl
Internet Things
Juan David Arias Correa, Alex Sandro Roschildt Pinto, Carlos Montez
2021 J jnl
IEEE Trans. Veh. Technol.
Renê Oliveira, Carlos Montez, Azzedine Boukerche, Michelle S. Wangham
2021 J jnl
Inf.
Suelen Laurindo, Ricardo de Moraes, Carlos Montez, Francisco Vasques
2021 C conf
IECON
Miguel Lino Ferreira Neto, Carlos Montez, Érico Leão, Aujor Tadeu Cavalca Andrade
2021 J jnl
IEEE Internet Things J.
Gabriel Germino Martins de Jesus, Richard Demo Souza, Carlos Montez, Arliones Hoeller
2020 J jnl
Sensors
Rogério Antônio Casagrande, Ricardo de Moraes, Carlos Montez, Francisco Vasques, Érico Leão
2020 C conf
ETFA
Suelen Laurindo, Ricardo de Moraes, Carlos Montez, Francisco Vasques
2020 conf
DoCEIS
Suelen Laurindo, Ricardo de Moraes, Carlos Montez
2020 J jnl
Sensors
Miguel Lino Ferreira Neto, Érico Leão, André Soares, Carlos Montez, Francisco Vasques, Ricardo de Moraes
2019 C conf
IECON
Miguel Lino Ferreira Neto, Vitor Vasconcelos, Álvaro Ian, Érico Leão, André Soares, Carlos Montez
2019 C conf
IECON
Eduardo Silva Pino, Carlos Montez, Odilson T. Valle, Érico Leão, Ricardo de Moraes
2019 C conf
IECON
D. Siedersberger, Carlos Montez, Érico Leão, Francisco Vasques
2019 conf
ADHOC-NOW
Suelen Laurindo, Ricardo de Moraes, Carlos Montez, Francisco Vasques
2018 C conf
INDIN
Érico Leão, Vitor Vasconcelos, Paulo Portugal, Carlos Montez, Ricardo de Moraes
2018 J jnl
Sensors
Suelen Laurindo, Ricardo de Moraes, Ríad Nassiffe, Carlos Montez, Francisco Vasques
2018 C conf
INDIN
Aujor Tadeu C. Andrade, D. Siedersberger, Carlos Montez, Ricardo de Moraes, Érico Leão, Francisco Vasques
2018 J jnl
Int. J. Commun. Syst.
Odilson T. Valle, Gerson F. Budke, Carlos Montez, Ricardo de Moraes, Francisco Vasques
2018 C conf
INDIN
Rogério Antônio Casagrande, Ricardo de Moraes, Carlos Montez, Analúcia Schiaffino Morales, Luciana Rech
2017 J jnl
Sensors
Leonardo Martins Rodrigues, Carlos Montez, Ricardo de Moraes, Paulo Portugal, Francisco Vasques
2017 J jnl
Sensors
Érico Leão, Carlos Montez, Ricardo de Moraes, Paulo Portugal, Francisco Vasques
2017 J jnl
Int. J. Distributed Sens. Networks
Érico Leão, Ricardo de Moraes, Carlos Montez, Paulo Portugal, Francisco Vasques
2017 C conf
ETFA
L. Constante, Jim Lau, Ricardo de Moraes, Gustavo Medeiros de Araújo, Carlos Montez, Érico Leão
2017 J jnl
J. Sens. Actuator Networks
Leonardo Martins Rodrigues, Carlos Montez, Gerson F. Budke, Francisco Vasques, Paulo Portugal
2017 J jnl
Ad Hoc Networks
Renê Oliveira, Carlos Montez, Azzedine Boukerche, Michelle S. Wangham
2017 C conf
WFCS
Suelen Laurindo, Ríad Nassiffe, Ricardo de Moraes, Carlos Montez, Gustavo Medeiros de Araújo, Odilson T. Valle
2017 J jnl
Sensors
Érico Leão, Carlos Montez, Ricardo de Moraes, Paulo Portugal, Francisco Vasques
2016 C conf
IECON
Érico Leão, Francisco Vasques, Paulo Portugal, Ricardo de Moraes, Carlos Montez
2016 C conf
WFCS
Odilson T. Valle, Gerson F. Budke, Carlos Montez, Alex R. Pinto, Fernando Hernandez, Francisco Vasques, Fabian Vargas, Edmundo Gatti
2016 C conf
WFCS
Leonardo Martins Rodrigues, Carlos Montez, Francisco Vasques, Paulo Portugal
2016 J jnl
Sensors
Odilson T. Valle, Carlos Montez, Gustavo Medeiros de Araújo, Francisco Vasques, Ricardo de Moraes
2016 C conf
IECON
Aujor Tadeu C. Andrade, Carlos Montez, Ricardo de Moraes, Alex R. Pinto, Francisco Vasques, G. L. da Silva
2016 C conf
WFCS
Hector Leon, Carlos Montez, Marcelo Ricardo Stemmer, Francisco Vasques
2015 C conf
WFCS
Odilson T. Valle, Carlos Montez, Gustavo Medeiros de Araújo, Ricardo de Moraes, Francisco Vasques
2015 C conf
WFCS
Tiago Semprebom, Carlos Montez, Gustavo Medeiros de Araújo, Paulo Portugal
2015 C conf
INDIN
Robson Costa, Paulo Portugal, Francisco Vasques, Carlos Montez, Ricardo de Moraes
2014 J jnl
Inf. Fusion
Alex R. Pinto, Carlos Montez, Gustavo Medeiros de Araújo, Francisco Vasques, Paulo Portugal
2014 C conf
INDIN
Érico Leão, Francisco Vasques, Paulo Portugal, Carlos Montez
2014 C conf
INDIN
Tiago Semprebom, Ricardo de Moraes, Carlos Montez, Paulo Portugal, Francisco Vasques
2013 J jnl
EURASIP J. Wirel. Commun. Netw.
Tiago Semprebom, Carlos Montez, Francisco Vasques
2013 C conf
INDIN
Tiago Semprebom, Alex R. Pinto, Carlos Montez, Francisco Vasques
2013 C conf
ETFA
Mitchel S. Felske, Carlos Montez, Alex R. Pinto, Francisco Vasques, Paulo Portugal
2013 conf
SBESC
Luiz Fernando Schrickte, Carlos Montez, Rômulo Silva de Oliveira, Alex R. Pinto
2013 C conf
WorldCIST
Odilson T. Valle, Andre V. Milack, Carlos Montez, Paulo Portugal, Francisco Vasques
2012 conf
SBESC
Tiago Semprebom, Gustavo Zomer, Andre V. Milack, Carlos Montez, Alex R. Pinto
2012 C conf
ETFA
Gerson F. Budke, Carlos Montez, Ricardo de Moraes, Paulo Portugal
2012 conf
ISWCS
Odilson T. Valle, Carlos Montez, Paulo Portugal, Francisco Vasques, Daniel G. Costa
2012 C conf
WFCS
Odilson T. Valle, Andre V. Milack, Carlos Montez, Paulo Portugal, Francisco Vasques
2012 C conf
ETFA
Tiago Semprebom, Carlos Montez, Gustavo Zomer, Francisco Vasques
2012 conf
LATW
Alex R. Pinto, Adriano Mauro Cansian, José Marcio Machado, Carlos Montez
2011 conf
SBESC
Gerson F. Budke, Carlos Montez, Ricardo de Moraes, Paulo Portugal
2011 conf
SBESC
Moacyr Franco M. Neto, Carlos Montez
2011 J jnl
J. Parallel Distributed Comput.
Patricia Della Méa Plentz, Carlos Montez, Rômulo Silva de Oliveira
2011 J jnl
Web Intell. Agent Syst.
Luciana Rech, Carlos Montez, Rômulo Silva de Oliveira
2011 J jnl
Comput. Informatics
Patricia Della Méa Plentz, Carlos Montez, Rômulo Silva de Oliveira
2011 C conf
ISADS
Ramon Lopes, Flávio Assis, Carlos Montez
2010 conf
LATW
Felipe Lavratti, Alex R. Pinto, Dárcio Prestes, Letícia Maria Veiras Bolzani, Fabian Vargas, Carlos Montez
2009 C conf
ETFA
Tiago Semprebom, Carlos Montez, Ricardo de Moraes, Francisco Vasques, Ricardo Felipe Custódio
2009 C conf
ETFA
Rômulo Silva de Oliveira, Carlos Montez, Rodrigo Lange
2008 C conf
ETFA
Patricia Della Méa Plentz, Carlos Montez, Rômulo Silva de Oliveira
2008 J jnl
Comput. Commun.
Patricia Della Méa Plentz, Carlos Montez, Rômulo Silva de Oliveira
2008 C conf
ETFA
Luciana Rech, Carlos Montez, Rômulo Silva de Oliveira, Fábio Reis Cecin, Cláudio Fernando Resin Geyer
2008 J jnl
Web Intell. Agent Syst.
Luciana Rech, Carlos Montez, Rômulo Silva de Oliveira
2007 C conf
ETFA
Patricia Della Méa Plentz, Carlos Montez, Rômulo Silva de Oliveira
2007 C conf
ISORC
Cássia Yuri Tatibana, Carlos Montez, Rômulo Silva de Oliveira
2007 conf
SEUS
Cássia Yuri Tatibana, Carlos Montez, Rômulo Silva de Oliveira
2006 C conf
ETFA
Luciana Rech, Carlos Montez, Rômulo Silva de Oliveira
2006 Misc conf
IRI
Luciana Rech, Carlos Montez, Rômulo Silva de Oliveira
2006 conf
WebMedia
Tiago Semprebom, Rômulo Silva de Oliveira, Carlos Montez
2005 conf
SCCC
Rodrigo Gonçalves, Rômulo Silva de Oliveira, Carlos Montez
2005 conf
IAT
Luciana Rech, Rômulo Silva de Oliveira, Carlos Montez
2005 C conf
ETFA
Cássia Yuri Tatibana, Rômulo Silva de Oliveira, Carlos Montez
2005 B conf
EDOC
Giuliana Teixeira Santos, Lau Cheuk Lung, Carlos Montez
2005 C conf
ETFA
Patricia Della Méa Plentz, Rômulo Silva de Oliveira, Carlos Montez
2003 conf
WORDS
Joni da Silva Fraga, Ricardo J. Rabelo, Frank Siqueira, Carlos Montez, Rômulo Silva de Oliveira
2002 conf
SCCC
Carlos Montez
2002 B conf
SRDS
Carlos Montez, Joni da Silva Fraga
1999 C conf
ISORC
Carlos Montez, Joni da Silva Fraga, Jean-Marie Farines, Rômulo Silva de Oliveira
1998 conf
SCCC
Carlos Montez, Rômulo Silva de Oliveira, Joni da Silva Fraga
1995 conf
FTDCS
Carlos Montez, Joni da Silva Fraga, Jean-Marie Farines, Olinto Furtado, Frank Siqueira
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