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

Преобразования типов

Клиент стремится быть максимально гибким в плане поддержки типов переменных — как для вставки, так и для маршалинга ответов. В большинстве случаев для типа столбца ClickHouse существует эквивалентный тип Golang, например UInt64 и uint64. Такие логические соответствия должны поддерживаться всегда. Также могут использоваться типы переменных, которые можно вставлять в столбцы или применять для получения ответа, если предварительно выполняется преобразование переменной или полученных данных. Клиент стремится поддерживать такие преобразования прозрачно, чтобы пользователям не приходилось заранее точно приводить данные к нужному типу перед вставкой, а также чтобы обеспечить гибкий маршалинг во время выполнения запроса. При этом такие прозрачные преобразования не допускают потери точности. Например, uint32 нельзя использовать для получения данных из столбца UInt64. И наоборот, строку можно вставить в поле DateTime64, если она соответствует требованиям формата. Поддерживаемые в настоящее время преобразования типов для примитивных типов собраны здесь. Эта работа продолжается и может быть разделена на вставку (Append/AppendRow) и чтение (через Scan). Если вам нужна поддержка определённого преобразования, создайте issue. Стандартный интерфейс database/sql должен поддерживать те же типы, что и API ClickHouse. Есть несколько исключений, в основном для сложных типов; они описаны в разделах ниже. Как и API ClickHouse, клиент стремится быть максимально гибким в плане поддержки типов переменных — как для вставки, так и для маршалинга ответов.

Сложные типы

Date/DateTime

Клиент Go для ClickHouse поддерживает типы даты и даты/времени Date, Date32, DateTime и DateTime64. Даты можно вставлять как строки в формате 2006-01-02 или с помощью встроенных типов Go time.Time{} и sql.NullTime. Для DateTime также поддерживаются эти типы, но строки должны передаваться в формате 2006-01-02 15:04:05 с необязательным смещением часового пояса, например 2006-01-02 15:04:05 +08:00. При чтении также поддерживаются time.Time{} и sql.NullTime, а также любая реализация интерфейса sql.Scanner. Обработка информации о часовом поясе зависит от типа ClickHouse и от того, вставляется значение или читается:
  • DateTime/DateTime64
    • Во время вставки значение отправляется в ClickHouse в формате Unix-временной метки. Если часовой пояс не указан, клиент будет считать, что используется локальный часовой пояс клиента. time.Time{} или sql.NullTime будут соответствующим образом преобразованы в время эпохи Unix.
    • Во время чтения при возврате значения time.Time будет использоваться часовой пояс столбца, если он задан. В противном случае будет использоваться часовой пояс сервера.
  • Date/Date32
    • Во время вставки при преобразовании даты в Unix-временную метку учитывается ее часовой пояс, то есть перед сохранением как даты к ней применяется соответствующее смещение часового пояса, поскольку типы Date в ClickHouse не содержат информации о локали. Если в строковом значении он не указан, будет использоваться локальный часовой пояс.
    • Во время чтения даты, считанные в экземпляры time.Time{} или sql.NullTime{}, возвращаются без информации о часовом поясе.

Типы Time/Time64

Типы столбцов Time и Time64 хранят значения времени суток без компонента даты. Оба сопоставляются с типом Go time.Duration.
  • Time хранит время с точностью до секунды.
  • Time64(precision) поддерживает точность меньше секунды (как DateTime64), где precision принимает значения от 0 до 9.

Array

Значения типа Array следует вставлять как срезы. Правила для типов элементов такие же, как и для примитивного типа, то есть по возможности элементы будут преобразованы. При вызове Scan следует передавать указатель на срез.
Полный пример

Map

Значения типа Map следует вставлять в виде map в Go, при этом ключи и значения должны соответствовать правилам преобразования типов, определённым ранее.
Полный пример
При использовании API database/sql для значений Map требуется строгая типизация — interface{} нельзя использовать в качестве типа значения. Например, для поля Map(String,String) нельзя передать map[string]interface{}; вместо него нужно использовать map[string]string. Переменная типа interface{} при этом всегда будет совместимой и может использоваться для более сложных структур.Полный пример

Tuple

Тип Tuple представляет собой группу столбцов произвольной длины. Столбцы могут быть либо явно именованными, либо можно указать только их тип, например.
Из этих подходов именованные Tuple обеспечивают большую гибкость. Если безымянные Tuple нужно вставлять и читать с помощью срезов, то именованные Tuple также совместимы с Map.
Полный пример Примечание: типизированные срезы и значения типа Map поддерживаются при условии, что все подстолбцы в именованном Tuple имеют один и тот же тип.

Nested

Поле Nested эквивалентно Array из именованных Tuple. Использование зависит от того, установил ли пользователь для flatten_nested значение 1 или 0. Если установить flatten_nested в 0, столбцы Nested останутся единым массивом Tuple. Это позволяет использовать срезы map для вставки и извлечения, а также произвольные уровни вложенности. Ключ map должен совпадать с именем столбца, как показано в примере ниже. Примечание: поскольку map представляют Tuple, они должны иметь тип map[string]interface{}. В настоящее время значения не имеют строгой типизации.
Полный пример — flatten_tested=0 Если для flatten_nested используется значение по умолчанию, равное 1, вложенные столбцы преобразуются в отдельные массивы. Для вставки и чтения данных в этом случае нужно использовать вложенные срезы. Хотя произвольные уровни вложенности могут работать, официально это не поддерживается.
Полный пример — flatten_nested=1 Примечание: столбцы Nested должны иметь одинаковую размерность. Например, в приведённом выше примере Col_2_2 и Col_2_1 должны содержать одинаковое количество элементов. Благодаря более простому интерфейсу и официальной поддержке вложенных структур мы рекомендуем flatten_nested=0.

Гео-типы

Клиент поддерживает гео-типы Point, Ring, LineString, Polygon, MultiPolygon и MultiLineString. В Go эти типы представлены с помощью пакета github.com/paulmach/orb.
Полный пример

UUID

Тип UUID поддерживается пакетом github.com/google/uuid. Вы также можете отправлять и сериализовать UUID как строку или как любой тип, реализующий sql.Scanner или Stringify.
Полный пример

Decimal

Поскольку в Go нет встроенного типа Decimal, мы рекомендуем использовать сторонний пакет github.com/shopspring/decimal, чтобы работать с типами Decimal нативно, не изменяя исходные запросы.
Может возникнуть соблазн использовать вместо него Float, чтобы избежать сторонних зависимостей. Однако учтите, что типы Float в ClickHouse не рекомендуется использовать, когда требуется точность значений.Если вы всё же решите использовать на стороне клиента встроенный тип Float в Go, необходимо явно преобразовать Decimal в Float с помощью функции toFloat64() или её вариантов в запросах ClickHouse. Имейте в виду, что такое преобразование может привести к потере точности.
Полный пример

Nullable

Значение Nil в Go соответствует NULL в ClickHouse. Его можно использовать, если поле объявлено как Nullable. Во время вставки Nil можно передавать как для обычного столбца, так и для столбца типа Nullable. В первом случае будет сохранено значение по умолчанию для этого типа, например пустая строка для string. Для Nullable-варианта в ClickHouse будет сохранено значение NULL. При сканировании пользователь должен передать указатель на тип, который поддерживает nil, например *string, чтобы представить значение nil для поля Nullable. В примере ниже col1, имеющий тип Nullable(String), получает **string. Это позволяет представить nil.
Полный пример Клиент также поддерживает типы sql.Null*, например sql.NullInt64. Они совместимы с соответствующими типами ClickHouse.

Большие целые числа

Числовые типы размером более 64 бит представлены с помощью встроенного в Go пакета big.
Полный пример

BFloat16

BFloat16 — это 16-битный тип чисел с плавающей запятой brain float, используемый в рабочих нагрузках машинного обучения. В Go значения BFloat16 записываются и считываются как float32. Для вариантов Nullable используется sql.NullFloat64.
Полный пример

QBit

QBit — это экспериментальный тип столбца для хранения векторных эмбеддингов в бит-срезовом формате, оптимизированный для поиска по сходству векторов. Для его использования должна быть включена настройка allow_experimental_qbit_type. В Go столбец QBit(Float32, N) вставляется и считывается как []float32, где N — размерность вектора.
Полный пример
Последнее изменение 1 июля 2026 г.