Перейти к основному содержанию

Вставка данных с помощью ClickHouse Connect: расширенные возможности

InsertContexts

ClickHouse Connect выполняет все вставки в рамках InsertContext. InsertContext включает все значения, переданные в качестве аргументов в метод клиента insert. Кроме того, при первоначальном создании InsertContext ClickHouse Connect получает типы данных для столбцов, в которые выполняется вставка, что необходимо для эффективной вставки в Native format. При повторном использовании InsertContext для нескольких вставок этот “предварительный запрос” не выполняется, и вставки выполняются быстрее и эффективнее. InsertContext можно получить с помощью метода клиента create_insert_context. Этот метод принимает те же аргументы, что и функция insert. Обратите внимание, что при повторном использовании следует изменять только свойство data у InsertContext. Это соответствует его назначению — предоставлять объект для многократной вставки новых данных в одну и ту же таблицу.
test_data = [[1, 'v1', 'v2'], [2, 'v3', 'v4']]
ic = test_client.create_insert_context(table='test_table', data='test_data')
client.insert(context=ic)
assert client.command('SELECT count() FROM test_table') == 2
new_data = [[3, 'v5', 'v6'], [4, 'v7', 'v8']]
ic.data = new_data
client.insert(context=ic)
qr = test_client.query('SELECT * FROM test_table ORDER BY key DESC')
assert qr.row_count == 4
assert qr[0][0] == 4
InsertContexts содержат изменяемое состояние, которое обновляется в процессе вставки, поэтому они не являются потокобезопасными.

Форматы записи

Форматы записи в настоящее время реализованы для ограниченного числа типов. В большинстве случаев ClickHouse Connect попытается автоматически определить подходящий формат записи для столбца, проверяя тип первого значения данных (не null). Например, при вставке в столбец DateTime, если первое вставляемое значение — целое число Python, ClickHouse Connect напрямую вставит это целое значение, предполагая, что оно представляет собой секунды epoch. В большинстве случаев переопределять формат записи для типа данных не требуется, однако для этого на глобальном уровне можно использовать соответствующие методы из пакета clickhouse_connect.datatypes.format.

Параметры формата записи

Тип ClickHouseНативный тип PythonФорматы записиКомментарии
Int[8-64], UInt[8-32]int-
UInt64int
[U]Int[128,256]int
BFloat16float
Float32float
Float64float
Decimaldecimal.Decimal
Stringstring
FixedStringbytesstringЕсли выполнять вставку как строки, дополнительные байты будут заполнены нулями
Enum[8,16]string
Datedatetime.dateintClickHouse хранит значения Date как количество дней с 01/01/1970. Предполагается, что типы int содержат это значение “epoch date”
Date32datetime.dateintТо же, что и Date, но для более широкого диапазона дат
DateTimedatetime.datetimeintClickHouse хранит DateTime как количество секунд с начала эпохи Unix. Предполагается, что типы int содержат это значение “epoch second”
DateTime64datetime.datetimeintdatetime.datetime в Python ограничен точностью до микросекунд. Доступно исходное 64-битное значение int
Timedatetime.timedeltaint, string, timeClickHouse хранит DateTime как количество секунд с начала эпохи Unix. Предполагается, что типы int содержат это значение “epoch second”
Time64datetime.timedeltaint, string, timedatetime.timedelta в Python ограничен точностью до микросекунд. Доступно исходное 64-битное значение int
IPv4ipaddress.IPv4AddressstringСтроки в корректном формате можно вставлять как IPv4-адреса
IPv6ipaddress.IPv6AddressstringСтроки в корректном формате можно вставлять как IPv6-адреса
Tupledict or tuple
Mapdict
NestedSequence[dict]
UUIDuuid.UUIDstringСтроки в корректном формате можно вставлять как UUID ClickHouse
JSON/Object(‘json’)dictstringВ JSON-столбцы можно вставлять как словари, так и JSON-строки (обратите внимание: Object('json') устарел)
VariantobjectВ настоящее время все значения Variant вставляются как Strings и разбираются сервером ClickHouse
DynamicobjectПредупреждение — в настоящее время любые вставки в столбец типа Dynamic сохраняются как ClickHouse String

Специализированные методы вставки

ClickHouse Connect предоставляет специализированные методы вставки для распространённых форматов данных:
  • insert_df — Вставка Pandas DataFrame. Вместо Python-аргумента data типа Sequence of Sequences этот метод в качестве второго параметра принимает аргумент df, который должен быть экземпляром Pandas DataFrame. ClickHouse Connect автоматически обрабатывает DataFrame как ориентированный по столбцам источник данных, поэтому параметр column_oriented не требуется и недоступен.
  • insert_arrow — Вставка таблицы PyArrow. ClickHouse Connect передаёт таблицу Arrow на сервер ClickHouse без изменений для обработки, поэтому помимо table и arrow_table доступны только аргументы database и settings.
  • insert_df_arrow — Вставка Pandas DataFrame с backend’ом Arrow или Polars DataFrame. ClickHouse Connect автоматически определяет, относится ли DataFrame к типу Pandas или Polars. Если это Pandas, выполняется проверка того, что backend dtype каждого столбца основан на Arrow; если хотя бы для одного столбца это не так, будет сгенерирована ошибка.
Массив NumPy является допустимым Sequence of Sequences и может использоваться как аргумент data для основного метода insert, поэтому отдельный специализированный метод не требуется.

Вставка из Pandas DataFrame

import clickhouse_connect
import pandas as pd

client = clickhouse_connect.get_client()

df = pd.DataFrame({
    "id": [1, 2, 3],
    "name": ["Alice", "Bob", "Joe"],
    "age": [25, 30, 28],
})

client.insert_df("users", df)

Вставка таблицы PyArrow

import clickhouse_connect
import pyarrow as pa

client = clickhouse_connect.get_client()

arrow_table = pa.table({
    "id": [1, 2, 3],
    "name": ["Alice", "Bob", "Joe"],
    "age": [25, 30, 28],
})

client.insert_arrow("users", arrow_table)

Вставка DataFrame на базе Arrow (pandas 2.x)

import clickhouse_connect
import pandas as pd

client = clickhouse_connect.get_client()

# Преобразование в типы данных с поддержкой Arrow для повышения производительности
df = pd.DataFrame({
    "id": [1, 2, 3],
    "name": ["Alice", "Bob", "Joe"],
    "age": [25, 30, 28],
}).convert_dtypes(dtype_backend="pyarrow")

client.insert_df_arrow("users", df)

Часовые пояса

При вставке объектов Python datetime.datetime в столбцы ClickHouse DateTime или DateTime64 ClickHouse Connect автоматически обрабатывает информацию о часовом поясе. Поскольку ClickHouse хранит все значения DateTime как Unix-временные метки без привязки к часовому поясу (секунды или доли секунды с начала эпохи), преобразование часового пояса при вставке автоматически выполняется на стороне клиента.

Объекты datetime с часовым поясом

Если вы выполняете вставку объекта Python datetime.datetime с часовым поясом, ClickHouse Connect автоматически вызовет .timestamp(), чтобы преобразовать его в Unix-временную метку, которая корректно учитывает смещение часового пояса. Это означает, что вы можете выполнять вставку объектов datetime из любого часового пояса, и они будут правильно сохраняться как эквивалентная временная метка UTC.
import clickhouse_connect
from datetime import datetime
import pytz

client = clickhouse_connect.get_client()
client.command("CREATE TABLE events (event_time DateTime) ENGINE Memory")

# Вставка объектов datetime с часовым поясом
denver_tz = pytz.timezone('America/Denver')
tokyo_tz = pytz.timezone('Asia/Tokyo')

data = [
    [datetime(2023, 6, 15, 10, 30, 0, tzinfo=pytz.UTC)],
    [denver_tz.localize(datetime(2023, 6, 15, 10, 30, 0))],
    [tokyo_tz.localize(datetime(2023, 6, 15, 10, 30, 0))]
]

client.insert('events', data, column_names=['event_time'])
results = client.query("SELECT * from events")
print(*results.result_rows, sep="\n")
# Вывод:
# (datetime.datetime(2023, 6, 15, 10, 30),)
# (datetime.datetime(2023, 6, 15, 16, 30),)
# (datetime.datetime(2023, 6, 15, 1, 30),)
В этом примере все три объекта datetime представляют разные моменты времени, поскольку у них разные часовые пояса. Каждый из них будет корректно преобразован в соответствующую Unix-временную метку и сохранён в ClickHouse.
При использовании pytz необходимо вызывать метод localize(), чтобы добавить информацию о часовом поясе к naive datetime. Если передать tzinfo= напрямую в конструктор datetime, будут использованы некорректные исторические смещения. Для UTC корректно работает tzinfo=pytz.UTC. Подробнее см. в документации pytz.

Объекты datetime без часового пояса

Если вы выполняете вставку объекта Python datetime.datetime без часового пояса (без tzinfo), метод .timestamp() интерпретирует его как объект в локальном часовом поясе системы. Чтобы избежать неоднозначности, рекомендуется:
  1. Всегда использовать при вставке объекты datetime с часовым поясом, или
  2. Убедиться, что часовой пояс системы установлен на UTC, или
  3. Вручную преобразовывать значения во временные метки epoch перед вставкой
import clickhouse_connect
from datetime import datetime
import pytz

client = clickhouse_connect.get_client()

# Рекомендуется: всегда используйте объекты datetime с часовым поясом
utc_time = datetime(2023, 6, 15, 10, 30, 0, tzinfo=pytz.UTC)
client.insert('events', [[utc_time]], column_names=['event_time'])

# Альтернатива: вручную преобразуйте в временную метку Unix
naive_time = datetime(2023, 6, 15, 10, 30, 0)
epoch_timestamp = int(naive_time.replace(tzinfo=pytz.UTC).timestamp())
client.insert('events', [[epoch_timestamp]], column_names=['event_time'])

Столбцы DateTime с метаданными часового пояса

Столбцы ClickHouse можно определять с метаданными часового пояса (например, DateTime('America/Denver') или DateTime64(3, 'Asia/Tokyo')). Эти метаданные не влияют на способ хранения данных (они по-прежнему сохраняются как UTC-временные метки), но определяют часовой пояс, который используется при запросе данных из ClickHouse. При вставке в такие столбцы ClickHouse Connect преобразует ваш объект Python datetime в Unix-временную метку (с учётом его часового пояса, если он задан). Когда вы запрашиваете данные, ClickHouse Connect вернёт datetime, преобразованный в часовой пояс столбца, независимо от того, какой часовой пояс использовался при вставке.
import clickhouse_connect
from datetime import datetime
import pytz

client = clickhouse_connect.get_client()

# Создание таблицы с метаданными часового пояса Los Angeles
client.command("CREATE TABLE events (event_time DateTime('America/Los_Angeles')) ENGINE Memory")

# Вставка времени по Нью-Йорку (10:30 EDT, что соответствует 14:30 UTC)
ny_tz = pytz.timezone("America/New_York")
data = ny_tz.localize(datetime(2023, 6, 15, 10, 30, 0))
client.insert("events", [[data]], column_names=["event_time"])

# При запросе время автоматически преобразуется в часовой пояс Los Angeles
# 10:30 по Нью-Йорку (UTC-4) = 14:30 UTC = 7:30 по Los Angeles (UTC-7)
results = client.query("select * from events")
print(*results.result_rows, sep="\n")
# Вывод:
# (datetime.datetime(2023, 6, 15, 7, 30, tzinfo=<DstTzInfo 'America/Los_Angeles' PDT-1 day, 17:00:00 DST>),)

Вставка из файлов

Пакет clickhouse_connect.driver.tools включает метод insert_file, который позволяет вставлять данные напрямую из файловой системы в существующую таблицу ClickHouse. Разбор данных выполняет ClickHouse server. insert_file принимает следующие параметры:
ParameterTypeDefaultDescription
parameterTypeПо умолчаниюОписание
clientClientОбязательноdriver.Client, используемый для выполнения вставки
tablestrОбязательноТаблица ClickHouse, в которую выполняется вставка. Допускается полное имя таблицы (включая базу данных).
file_pathstrОбязательноПуть файловой системы к файлу с данными
fmtstrCSV, CSVWithNamesВходной формат ClickHouse для файла. Если column_names не указан, используется CSVWithNames
column_namesSequence of strNoneСписок имён столбцов в файле с данными. Не требуется для форматов, включающих имена столбцов
databasestrNoneБаза данных таблицы. Игнорируется, если таблица указана с полным именем. Если не указано, для вставки будет использоваться база данных клиента
settingsdictNoneСм. описание settings.
compressionstrNoneПоддерживаемый тип сжатия ClickHouse (zstd, lz4, gzip), используемый для HTTP-заголовка Content-Encoding
Для файлов с несогласованными данными или значениями даты/времени в необычном формате этот метод поддерживает settings, применимые к импорту данных (например, input_format_allow_errors_num и input_format_allow_errors_num).
import clickhouse_connect
from clickhouse_connect.driver.tools import insert_file

client = clickhouse_connect.get_client()
insert_file(client, 'example_table', 'my_data.csv',
            settings={'input_format_allow_errors_ratio': .2,
                      'input_format_allow_errors_num': 5})
Последнее изменение 10 июня 2026 г.