You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将含UUID、DateTime数组的pandas DataFrame写入ClickHouse表

解决步骤

第一步:DataFrame数据预处理

所有报错的核心原因是数据类型和ClickHouse表结构不匹配,先执行以下转换:

import numpy as np
from datetime import datetime

# 1. 转换UUID列为字符串,匹配ClickHouse UUID类型输入要求
df['UserID'] = df['UserID'].astype(str)

# 2. 转换Views数组为Python原生列表,同时移除时间的时区信息避免范围报错
df['Views'] = df['Views'].apply(
    lambda x: [
        dt.replace(tzinfo=None) if isinstance(dt, datetime) and dt.tzinfo else dt 
        for dt in x.tolist()
    ] if isinstance(x, np.ndarray) else x
)

# 3. 转换Events数组为Python原生列表
df['Events'] = df['Events'].apply(lambda x: x.tolist() if isinstance(x, np.ndarray) else x)

# 4. 转换RecDate为无时区的Python datetime类型
df['RecDate'] = df['RecDate'].apply(lambda x: x.to_pydatetime().replace(tzinfo=None))

第二步:两种可行插入方案

方案1:使用clickhouse_driver插入(推荐)

from clickhouse_driver import Client

# 初始化ClickHouse客户端,端口默认9000,按需修改配置
client = Client(
    host='localhost',
    port=9000,
    user='default',
    password='',
    database='default'
)

# 执行插入
client.insert_dataframe(
    'INSERT INTO rec_eval_data VALUES',
    df,
    settings={'use_numpy': True}
)

方案2:使用pandahouse插入

添加method='POST'参数即可解决只读请求问题:

import pandahouse as ph

connection = {
    'database': 'default',
    'host': 'http://localhost:8123',
    'user': 'default',
    'password': ''
}

ph.to_clickhouse(
    df,
    'rec_eval_data',
    index=False,
    chunksize=100000,
    connection=connection,
    method='POST'
)

过往方案报错原因说明

  • 原生插入报错:数组列是numpy.ndarray格式,非Python原生列表,或时间列带时区导致范围溢出
  • pandahouse报错:未指定POST请求方式,默认GET请求仅支持查询操作
  • insert_dataframe报错:数组列未从numpy.ndarray转为Python原生列表
  • 逐行插入报错:拼接SQL时未给UUID等字符串类型加单引号,ClickHouse将带横杠的UUID识别为减法运算,所以报找不到对应列的错误,该写法存在SQL注入风险,不推荐使用

内容的提问来源于stack exchange,提问作者Laurel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 09:39:04