Ran Gu

81 papers B 1C 3Journal 61Unranked 16
YearRankTypeTitle / Venue / Authors
2026 J jnl
J. Optim. Theory Appl.
Xinyue Huo, Ran Gu
2026 J jnl
Discret. Appl. Math.
Ran Gu
2026 J jnl
CoRR
Qingqing Zhu, Qiao Jin, Tejas Sudharshan Mathai, Yin Fang, Zhizheng Wang, Yifan Yang, Maame Sarfo-Gyamfi, Benjamin Hou, Ran Gu, Praveen Thoppey Srinivasan Balamuralikrishna, Kenneth C. Wang, Ronald M. Summers, Zhiyong Lu
2026 J jnl
IEEE Trans. Image Process.
Hongyu Li, Tianyi Xu, Zengyou Wang, Xiantong Zhen, Ran Gu, David Zhang, Jun Xu
2026 J jnl
CoRR
Tianhao Qian, Guilin Qi, Z. Y. Wu, Ran Gu, Xuanyi Liu, Canchen Lyu
2026 J jnl
Medical Image Anal.
He Li, Xiangde Luo, Jia Fu, Ran Gu, Wenjun Liao, Shichuan Zhang, Kang Li, Guotai Wang, Shaoting Zhang
2026 J jnl
Adv. Eng. Softw.
Yu Wang, Yue Li, Shunpeng Zhu, Ran Gu, Xinhao Shu, Zhengwei Fan, Shufeng Zhang
2025 J jnl
J. Appl. Math. Comput.
Ran Gu, Chaofeng Dong, Wei Wang
2025 J jnl
Discret. Math.
Ran Gu
2025 J jnl
Neural Networks
Chao Li, Yuchen Yang, Qiujia He, Ran Gu, Lei Zhang, Jun Xu
2025 J jnl
CoRR
Jiarui Cao, Zhiyang Zhang, Heming Wang, Jun Xu, Ling Lan, Ran Gu, Simon J. L. Billinge
2025 J jnl
CoRR
Bing Gao, Ran Gu, Shigui Ma
2025 J jnl
Int. J. Found. Comput. Sci.
Ran Gu, Shuaichao Wang
2024 J jnl
Discret. Appl. Math.
Ran Gu, Hui Lei, Yongtang Shi, Yiqiao Wang
2024 J jnl
Neurocomputing
Jiangshan Lu, Ran Gu, Wenjun Liao, Shichuan Zhang, Huijun Yu, Shaoting Zhang, Guotai Wang
2024 J jnl
Graphs Comb.
Ran Gu, Shuaichao Wang
2024 J jnl
IEEE Trans. Medical Imaging
Wenhui Lei, Qi Su, Tianyu Jiang, Ran Gu, Na Wang, Xinglong Liu, Guotai Wang, Xiaofan Zhang, Shaoting Zhang
2024 conf
ISBI
Yubo Zhou, Ran Gu, Shaoting Zhang, Guotai Wang
2023 J jnl
Medical Image Anal.
Ran Gu, Guotai Wang, Jiangshan Lu, Jingyang Zhang, Wenhui Lei, Yinan Chen, Wenjun Liao, Shichuan Zhang, Kang Li, Dimitris N. Metaxas, Shaoting Zhang
2023 J jnl
IEEE Trans. Medical Imaging
Ran Gu, Jingyang Zhang, Guotai Wang, Wenhui Lei, Tao Song, Xiaofan Zhang, Kang Li, Shaoting Zhang
2023 J jnl
Int. J. Prod. Res.
Shigui Ma, Yong He, Ran Gu
2023 J jnl
Comput. Methods Programs Biomed.
Guotai Wang, Xiangde Luo, Ran Gu, Shuojue Yang, Yijie Qu, Shuwei Zhai, Qianfei Zhao, Kang Li, Shaoting Zhang
2023 J jnl
IEEE Trans. Medical Imaging
Jingyang Zhang, Ran Gu, Peng Xue, Mianxin Liu, Hao Zheng, Yefeng Zheng, Lei Ma, Guotai Wang, Lixu Gu
2023 J jnl
IEEE Trans. Medical Imaging
Jianghao Wu, Guotai Wang, Ran Gu, Tao Lu, Yinan Chen, Wentao Zhu, Tom Vercauteren, Sébastien Ourselin, Shaoting Zhang
2023 J jnl
CoRR
Jianghao Wu, Guotai Wang, Ran Gu, Tao Lu, Yinan Chen, Wentao Zhu, Tom Vercauteren, Sébastien Ourselin, Shaoting Zhang
2023 conf
IPMI
Jianghao Wu, Ran Gu, Tao Lu, Shaoting Zhang, Guotai Wang
2022 J jnl
CoRR
Ran Gu, Guotai Wang, Jiangshan Lu, Jingyang Zhang, Wenhui Lei, Yinan Chen, Wenjun Liao, Shichuan Zhang, Kang Li, Dimitris N. Metaxas, Shaoting Zhang
2022 J jnl
CoRR
Ran Gu, Jiangshan Lu, Jingyang Zhang, Wenhui Lei, Xiaofan Zhang, Guotai Wang, Shaoting Zhang
2022 J jnl
CoRR
Ran Gu, Jingyang Zhang, Guotai Wang, Wenhui Lei, Tao Song, Xiaofan Zhang, Kang Li, Shaoting Zhang
2022 conf
ISBI
Jianghao Wu, Ran Gu, Guiming Dong, Guotai Wang, Shaoting Zhang
2022 conf
MICCAI (5)
Jingyang Zhang, Peng Xue, Ran Gu, Yuning Gu, Mianxin Liu, Yongsheng Pan, Zhiming Cui, Jiawei Huang, Lei Ma, Dinggang Shen
2022 J jnl
CoRR
Jingyang Zhang, Peng Xue, Ran Gu, Yuning Gu, Mianxin Liu, Yongsheng Pan, Zhiming Cui, Jiawei Huang, Lei Ma, Dinggang Shen
2022 J jnl
Appl. Math. Comput.
Ran Gu, Hui Lei, Yuejian Peng, Yongtang Shi
2022 J jnl
Discret. Appl. Math.
Ran Gu, Hui Lei, Yongtang Shi
2022 J jnl
CoRR
Guotai Wang, Xiangde Luo, Ran Gu, Shuojue Yang, Yijie Qu, Shuwei Zhai, Qianfei Zhao, Kang Li, Shaoting Zhang
2022 J jnl
Theor. Comput. Sci.
Ran Gu, Gregory Z. Gutin, Shasha Li, Yongtang Shi, Zhenyu Taoqiu
2022 J jnl
J. Graph Theory
Ran Gu, Xiaofeng Gu, Yongtang Shi, Hua Wang
2021 J jnl
CoRR
Ran Gu, Qiang Du, Simon J. L. Billinge
2021 conf
ICISCAE (ACM)
Ran Gu
2021 J jnl
CoRR
Haochen Mei, Wenhui Lei, Ran Gu, Shan Ye, Zhengwentai Sun, Shichuan Zhang, Guotai Wang
2021 J jnl
CoRR
Wenhui Lei, Haochen Mei, Zhengwentai Sun, Shan Ye, Ran Gu, Huan Wang, Rui Huang, Shichuan Zhang, Shaoting Zhang, Guotai Wang
2021 J jnl
Neurocomputing
Haochen Mei, Wenhui Lei, Ran Gu, Shan Ye, Zhengwentai Sun, Shichuan Zhang, Guotai Wang
2021 J jnl
Neurocomputing
Wenhui Lei, Haochen Mei, Zhengwentai Sun, Shan Ye, Ran Gu, Huan Wang, Rui Huang, Shichuan Zhang, Shaoting Zhang, Guotai Wang
2021 J jnl
IEEE Trans. Medical Imaging
Ran Gu, Guotai Wang, Tao Song, Rui Huang, Michael Aertsen, Jan Deprest, Sébastien Ourselin, Tom Vercauteren, Shaoting Zhang
2021 conf
MICCAI (1)
Jingyang Zhang, Ran Gu, Guotai Wang, Lixu Gu
2021 conf
MICCAI (2)
Wenhui Lei, Wei Xu, Ran Gu, Hao Fu, Shaoting Zhang, Shichuan Zhang, Guotai Wang
2021 conf
MICCAI (3)
Ran Gu, Jingyang Zhang, Rui Huang, Wenhui Lei, Guotai Wang, Shaoting Zhang
2021 J jnl
CoRR
Ran Gu, Jingyang Zhang, Rui Huang, Wenhui Lei, Guotai Wang, Shaoting Zhang
2021 J jnl
Int. J. Prod. Res.
Shigui Ma, Yong He, Ran Gu
2021 J jnl
J. Comb. Optim.
Ran Gu, Yongtang Shi, Neng Fan
2021 J jnl
CoRR
Wenhui Lei, Qi Su, Ran Gu, Na Wang, Xinglong Liu, Guotai Wang, Xiaofan Zhang, Shaoting Zhang
2021 conf
HECKTOR@MICCAI
Jiangshan Lu, Wenhui Lei, Ran Gu, Guotai Wang
2021 conf
ISBI
Jingyang Zhang, Ran Gu, Guotai Wang, Hongzhi Xie, Lixu Gu
2021 J jnl
CoRR
Jingyang Zhang, Ran Gu, Guotai Wang, Hongzhi Xie, Lixu Gu
2021 C conf
COCOA
Ran Gu, Gregory Z. Gutin, Shasha Li, Yongtang Shi, Zhenyu Taoqiu
2020 J jnl
SIAM J. Discret. Math.
Ran Gu, Jiaao Li, Yongtang Shi
2020 J jnl
CoRR
Ran Gu, Guotai Wang, Tao Song, Rui Huang, Michael Aertsen, Jan Deprest, Sébastien Ourselin, Tom Vercauteren, Shaoting Zhang
2020 J jnl
Discret. Appl. Math.
Ran Gu, Xueliang Li
2020 conf
MyoPS@MICCAI
Shuwei Zhai, Ran Gu, Wenhui Lei, Guotai Wang
2020 J jnl
Theor. Comput. Sci.
Ran Gu, Yaping Mao, Guoju Ye
2020 J jnl
CoRR
Wenhui Lei, Wei Xu, Ran Gu, Hao Fu, Shaoting Zhang, Guotai Wang
2020 J jnl
CoRR
Chia-Hao Liu, Christopher J. Wright, Ran Gu, Sasaank Bandi, Allison Wustrow, Paul K. Todd, Daniel O'Nolan, Michelle L. Beauvais, James R. Neilson, Peter J. Chupas, Karena W. Chapman, Simon J. L. Billinge
2019 J jnl
Discret. Appl. Math.
Ran Gu, Hong-Jian Lai, Yanting Liang, Zhengke Miao, Meng Zhang
2019 conf
LABELS/HAL-MICCAI/CuRIOUS@MICCAI
Wenhui Lei, Huan Wang, Ran Gu, Shichuan Zhang, Shaoting Zhang, Guotai Wang
2019 B conf
KES
Shigui Ma, Yong He, Ran Gu, Sijie Li
2019 J jnl
Appl. Math. Comput.
Ran Gu, Bo Deng, Rui Li
2019 J jnl
IEEE Trans. Veh. Technol.
Carlos Vidal, Oliver Gross, Ran Gu, Phillip J. Kollmeyer, Ali Emadi
2018 conf
CSI@MICCAI
Huan Wang, Ran Gu, Zhongyu Li
2018 J jnl
Appl. Math. Comput.
Ran Gu, Xueliang Li, Zhongmei Qin, Yongtang Shi, Kang Yang
2018 J jnl
Appl. Math. Comput.
Ran Gu, Rui Li
2017 conf
COCOA (1)
Ran Gu, Yongtang Shi, Neng Fan
2016 J jnl
IEEE Trans. Veh. Technol.
Pawel Malysz, Jin Ye, Ran Gu, Hong Yang, Ali Emadi
2016 J jnl
Theor. Comput. Sci.
Ran Gu, Xueliang Li, Zhongmei Qin
2016 J jnl
J. Comb. Optim.
Ran Gu, Xueliang Li, Yuejian Peng, Yongtang Shi
2013 J jnl
J. Netw. Syst. Manag.
Yan Qiao, Xuesong Qiu, Luoming Meng, Ran Gu
2012 J jnl
Expert Syst. Appl.
Ke Xu, Jianzhong Zhou, Yongchuan Zhang, Ran Gu
2012 C conf
ISCC
Yan Qiao, Guanjue Wang, Xuesong Qiu, Ran Gu
2012 C conf
ISCC
Ran Gu, Yan Qiao, Xuesong Qiu
2011 J jnl
Expert Syst. Appl.
Ke Xu, Jianzhong Zhou, Ran Gu, Hui Qin
2010 conf
FSKD
Ke Xu, Jianzhong Zhou, Ran Gu, Hui Qin
2009 conf
FSKD (4)
Ke Xu, Jianzhong Zhou, Ran Gu, Hui Qin
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