From e0f93cf96d1ef50a789ff929f6459e25bd9989c5 Mon Sep 17 00:00:00 2001 From: Aleksey Myasnikov Date: Tue, 3 Sep 2024 23:54:47 +0300 Subject: [PATCH 01/44] go basic example --- .../example-app/go/_includes/run_custom.md | 8 +- .../example-app/go/_includes/run_docker.md | 4 +- ydb/docs/ru/core/dev/example-app/go/index.md | 315 ++++++++---------- 3 files changed, 140 insertions(+), 187 deletions(-) diff --git a/ydb/docs/ru/core/dev/example-app/go/_includes/run_custom.md b/ydb/docs/ru/core/dev/example-app/go/_includes/run_custom.md index a10b810ddefa..46280470f9a2 100644 --- a/ydb/docs/ru/core/dev/example-app/go/_includes/run_custom.md +++ b/ydb/docs/ru/core/dev/example-app/go/_includes/run_custom.md @@ -5,11 +5,11 @@ Выполните команду по следующему образцу: ``` bash -( export ="" && cd ydb-go-examples && \ -go run ./basic -ydb="?database=" ) +( export ="" && cd ydb-go-sdk/examples && \ +go run . -ydb="/" ) ``` -, где +где - `` - [эндпоинт](../../../../concepts/connect.md#endpoint). - `` - [путь базы данных](../../../../concepts/connect.md#database). @@ -20,5 +20,5 @@ go run ./basic -ydb="?database=" ) ``` bash ( export YDB_ACCESS_TOKEN_CREDENTIALS="t1.9euelZqOnJuJlc..." && cd ydb-go-examples && \ -go run ./basic -ydb="grpcs://ydb.example.com:2135?database=/somepath/somelocation" ) +go run ./basic -ydb="grpcs://ydb.example.com:2135/somepath/somelocation" ) ``` diff --git a/ydb/docs/ru/core/dev/example-app/go/_includes/run_docker.md b/ydb/docs/ru/core/dev/example-app/go/_includes/run_docker.md index 64bca8f51c9b..4f2df0aa6a48 100644 --- a/ydb/docs/ru/core/dev/example-app/go/_includes/run_docker.md +++ b/ydb/docs/ru/core/dev/example-app/go/_includes/run_docker.md @@ -1,6 +1,6 @@ Для соединения с развернутой локальной базой данных YDB по сценарию [Docker](../../../../quickstart.md) в конфигурации по умолчанию выполните следующую команду: ``` bash -( export YDB_ANONYMOUS_CREDENTIALS=1 && cd ydb-go-examples && \ -go run ./basic -ydb="grpc://localhost:2136?database=/local" ) +( export YDB_ANONYMOUS_CREDENTIALS=1 && cd ydb-go-sdk/examples && \ +go run ./basic/native/query -ydb="grpc://localhost:2136/local" ) ``` diff --git a/ydb/docs/ru/core/dev/example-app/go/index.md b/ydb/docs/ru/core/dev/example-app/go/index.md index 7d9cd9e8306c..cdfae2e737ec 100644 --- a/ydb/docs/ru/core/dev/example-app/go/index.md +++ b/ydb/docs/ru/core/dev/example-app/go/index.md @@ -9,7 +9,7 @@ Создайте рабочую директорию и выполните в ней из командной строки команду клонирования репозитория с github.com: ``` bash -git clone https://github.com/ydb-platform/ydb-go-examples/ +git clone git@github.com:ydb-platform/ydb-go-sdk.git ``` Далее из этой же рабочей директории выполните команду запуска тестового приложения, которая будет отличаться в зависимости от того, к какой базе данных необходимо подключиться. @@ -24,225 +24,178 @@ git clone https://github.com/ydb-platform/ydb-go-examples/ ```go import ( - // общие импорты из стандартной библиотеки - "context" - "log" - "path" - - // импорты пакетов ydb-go-sdk - "github.com/ydb-platform/ydb-go-sdk/v3" - "github.com/ydb-platform/ydb-go-sdk/v3/table" // для работы с table-сервисом - "github.com/ydb-platform/ydb-go-sdk/v3/table/options" // для работы с table-сервисом - "github.com/ydb-platform/ydb-go-sdk/v3/table/result" // для работы с table-сервисом - "github.com/ydb-platform/ydb-go-sdk/v3/table/result/named" // для работы с table-сервисом - "github.com/ydb-platform/ydb-go-sdk/v3/table/types" // для работы с типами YDB и значениями - "github.com/ydb-platform/ydb-go-sdk-auth-environ" // для аутентификации с использованием перменных окружения - "github.com/ydb-platform/ydb-go-yc" // для работы с YDB в Яндекс Облаке + "context" + "log" + "path" + + "github.com/ydb-platform/ydb-go-sdk/v3" + "github.com/ydb-platform/ydb-go-sdk/v3/query" ) ``` -Фрагмент кода приложения для инициализации драйвера: +Для взаимодействия с YDB необходимо создать объект подключения к YDB: ```go -ctx := context.Background() -// строка подключения -dsn := "grpcs://ydb.serverless.yandexcloud.net:2135/?database=/ru-central1/b1g8skpblkos03malf3s/etn01f8gv9an9sedo9fu" -// IAM-токен -token := "t1.9euelZrOy8aVmZKJm5HGjceMkMeVj-..." -// создаем объект подключения db, является входной точкой для сервисов YDB -db, err := ydb.Open(ctx, dsn, -// yc.WithInternalCA(), // используем сертификаты Яндекс Облака - ydb.WithAccessTokenCredentials(token), // аутентификация с помощью токена -// ydb.WithAnonimousCredentials(), // анонимная аутентификация (например, в docker ydb) -// yc.WithMetadataCredentials(token), // аутентификация изнутри виртуальной машины в Яндекс Облаке или из Яндекс Функции -// yc.WithServiceAccountKeyFileCredentials("~/.ydb/sa.json"), // аутентификация в Яндекс Облаке с помощью файла сервисного аккаунта -// environ.WithEnvironCredentials(ctx), // аутентификация с использованием переменных окружения -) +db, err := ydb.Open(context.Background(), "grpc://localhost:2136/local") if err != nil { // обработка ошибки подключения } -// закрытие драйвера по окончании работы программы обязательно -defer db.Close(ctx) ``` -Объект `db` является входной точкой для работы с сервисами `YDB`. -Для работы сервисом таблиц следует использовать клиента table-сервиса `db.Table()`. -Клиент table-сервиса предоставляет `API` для выполнения запросов над таблицами. -Наиболее востребован метод `db.Table().Do(ctx, op)`, который реализует фоновое создание сессий и повторные попытки выполнить пользовательскую операцию `op`, в которую пользовательскому коду отдается подготовленная сессия. -Сессия имеет исчерпывающее `API`, позволяющее выполнять `DDL`, `DML`, `DQL` и `TCL` запросы. +Метод `ydb.Open` возвращает в случае успеха экземпляр драйвера, которые выполняет ряд служебных функций, таких как актуализация сведений о кластере YDB и клиентская балансировка. -{% include [steps/02_create_table.md](../_includes/steps/02_create_table.md) %} +Метод `ydb.Open` принимает 2 обязательных аргемента: + +* контекст +* строка подключения к YDB. -Для создания таблиц используется метод `table.Session.CreateTable()`: +Также доступно множество опций подключения, позволяющих переопределить значения по умолчанию. + +Так, по умолчанию используется анонимная авторизация. А для подключения к кластеру YDB с использованием токена авторизации будет иметь вид: ```go -err = db.Table().Do(ctx, - func(ctx context.Context, s table.Session) (err error) { - return s.CreateTable(ctx, path.Join(db.Name(), "series"), - options.WithColumn("series_id", types.TypeUint64), // not null column - options.WithColumn("title", types.Optional(types.TypeUTF8)), - options.WithColumn("series_info", types.Optional(types.TypeUTF8)), - options.WithColumn("release_date", types.Optional(types.TypeDate)), - options.WithColumn("comment", types.Optional(types.TypeUTF8)), - options.WithPrimaryKeyColumn("series_id"), - ) - }, +db, err := ydb.Open(context.Background(), clusterEndpoint, + ydb.WithAccessTokenCredentials(token), ) -if err != nil { - // обработка ситуации, когда не удалось выполнить запрос -} ``` -С помощью метода `table.Session.DescribeTable()` можно вывести информацию о структуре таблицы и убедиться, что она успешно создалась: +Полный список провайдеров авторизации приведен в [документации ydb-go-sdk](https://github.com/ydb-platform/ydb-go-sdk?tab=readme-ov-file#credentials-) и в разделе [рецептов](../../../recipes/ydb-sdk/auth.md) + +В конце работы приложения для очистки ресурсов следует закрыть драйвер ```go -err = db.Table().Do(ctx, - func(ctx context.Context, s table.Session) (err error) { - desc, err := s.DescribeTable(ctx, path.Join(db.Name(), "series")) - if err != nil { - return - } - log.Printf("> describe table: %s\n", tableName) - for _, c := range desc.Columns { - log.Printf(" > column, name: %s, %s\n", c.Type, c.Name) - } - return - }, +defer db.Close(ctx) +``` + +Объект `db` является входной точкой для работы со всеми сервисами `YDB`: + +* `db.Query()` - клиент query-сервиса +* `db.Table()` - клиент table-сервиса +* `db.Discovery()` - клиент discovery-сервиса +* `db.Topic()` - клиент topic-сервиса +* `db.Coordination()` - клиент coordination-сервиса +* `db.Ratelimiter()` - клиент ratelimiter-сервиса +* `db.Scripting()` - клиент scriptingYQL-сервиса +* `db.Scheme()` - клиент scheme-сервиса +* `db.Operation()` - клиент operation-сервиса + +Для работы таблицами YDB следует использовать клиента query-сервиса `db.Query()`. Выполнение `DDL`, `DML`, `DQL` и `TCL` запросов в таблицы YDB осуществляется на специальных объекта - сессиях `query.Session`. Сессии YDB хранят контекст выполнения запросов (например, Prepared statements и транзакции) и позволяют осуществлять серверную балансировать балансировку нагрузки на узлы кластера YDB. + +Клиент query-сервиса предоставляет `API` для выполнения запросов над таблицами: + +* метод `db.Query().Do(ctx, op)` реализует фоновое создание сессий и повторные попытки выполнить пользовательскую операцию `op func(ctx context.Context, s query.Session) error`, в которую пользовательскому коду отдается подготовленная сессия `query.Session`. +* метод `db.Query().DoTx(ctx, op)` принимает пользовательскую операцию `op func(ctx context.Context, tx query.TxActor) error`, в которую пользовательскому коду отдается подготовленная (заранее открытая) транзакция `query.TxActor`. `Commit` транзакции также автоматический, если из пользовательской операции возвращается `nil`. В случае, если из пользовательской операции возвращается ошибка, то для текущей транзакции автоматически будет вызван `Rollback`. +* метод `db.Query().Exec` является вспомогательным и предназначен для выполнения единичного запроса **без результата** с автоматическими повторными попытками. Метод `Exec` возвращает `nil` в случае успешного выполнения запроса и ошибку, если операция не удалась. +* метод `db.Query().Query` является вспомогательным и предназначен для выполнения единичного запроса с автоматическими повторными попытками внутри. Метод `Query` возвращает в случае успеха материализованный результат запроса `query.Result`. `query.Result` позволяет итерироваться по вложенным спискам строк `query.ResultSet`. Для широких SQL-запросов, возвращающих большое количество строк, материализация результата может привести к проблеме `OOM killed`. +* метод `db.Query().QueryResultSet` является вспомогательным и предназначен для выполнения единичного запроса с автоматическими повторными попытками внутри. Метод `QueryResultSet` возвращает в случае успеха материализованный список строк `query.ResultSet`. Для широких SQL-запросов, возвращающих большое количество строк, материализация результата может привести к проблеме `OOM killed`. +* метод `db.Query().QueryRow` является вспомогательным и предназначен для выполнения единичного запроса с автоматическими повторными попытками внутри. Метод `QueryRow` возвращает в случае успеха единственную строку `query.Row`. + +{% include [steps/02_create_table.md](../_includes/steps/02_create_table.md) %} + +Пример создания таблицы: + +```go +import "github.com/ydb-platform/ydb-go-sdk/v3/query" +//////////////////////////////////////////////////// +err = db.Query().Exec(ctx, ` + CREATE TABLE IF NOT EXISTS series ( + series_id Bytes, + title Text, + series_info Text, + release_date Date, + comment Text, + + PRIMARY KEY(series_id) + )`, query.WithTxControl(query.NoTx()), ) if err != nil { - // обработка ситуации, когда не удалось выполнить запрос + // обработка ошибки выполнения запроса } ``` {% include [steps/04_query_processing.md](../_includes/steps/04_query_processing.md) %} -Для выполнения YQL-запросов используется метод `table.Session.Execute()`. -SDK позволяет в явном виде контролировать выполнение транзакций и настраивать необходимый режим выполнения транзакций с помощью структуры `table.TxControl`. +Для выполнения YQL-запросов без результата `query.Result` используется метод `query.Session.Exec`. Для выполнения YQL-запросов c результатом используется методы `query.Session.Query`, `query.Session.QueryResultSet` и `query.Session.QueryRow`. + +SDK позволяет в явном виде контролировать выполнение транзакций и настраивать необходимый режим выполнения транзакций с помощью структуры `query.TxControl`. ```go -var ( - readTx = table.TxControl( - table.BeginTx( - table.WithOnlineReadOnly(), - ), - table.CommitTx(), - ) +readTx := query.TxControl( + query.BeginTx( + query.WithSnapshotReadOnly(), + ), + query.CommitTx(), ) -err := db.Table().Do(ctx, - func(ctx context.Context, s table.Session) (err error) { - var ( - res result.Result - id uint64 // переменная для required результатов - title *string // указатель - для опциональных результатов - date *time.Time // указатель - для опциональных результатов - ) - _, res, err = s.Execute( - ctx, - readTx, - ` - DECLARE $seriesID AS Uint64; - SELECT - series_id, - title, - release_date - FROM - series - WHERE - series_id = $seriesID; - `, - table.NewQueryParameters( - table.ValueParam("$seriesID", types.Uint64Value(1)), // подстановка в условие запроса - ), - ) - if err != nil { - return err - } - defer res.Close() // закрытие result'а обязательно - log.Printf("> select_simple_transaction:\n") - for res.NextResultSet(ctx) { - for res.NextRow() { - // в ScanNamed передаем имена колонок из строки сканирования, - // адреса (и типы данных), куда следует присвоить результаты запроса - err = res.ScanNamed( - named.Optional("series_id", &id), - named.Optional("title", &title), - named.Optional("release_date", &date), - ) - if err != nil { - return err - } - log.Printf( - " > %d %s %s\n", - id, *title, *date, - ) - } - } - return res.Err() - }, +row, err := db.Query().QueryRow(ctx,` + DECLARE $seriesID AS Uint64; + SELECT + series_id, + title, + release_date + FROM + series + WHERE + series_id = $seriesID;`, + query.WithParameters( + ydb.ParamsBuilder().Param("$seriesID").Uint64(1).Build(), + ), + query.WithTxControl(readTx), ) if err != nil { // обработка ошибки выполнения запроса } ``` +Чтобы вычитать данные строки YDB `query.Row` используются методы `query.Row.Scan` (по индексу колонки), `query.Row.ScanNamed` (по названию колонки) и `query.Row.ScanStruct` (по названиям колонок, зафиксированных к тегах структуры): + +```go +var info struct { + SeriesID string `sql:"series_id"` + Title string `sql:"title"` + ReleaseDate time.Time `sql:"release_date"` +} +err = row.ScanStruct(&info) +if err != nil { + // обработка ошибки выполнения запроса +} +``` + {% include [scan_query.md](../_includes/steps/08_scan_query.md) %} -Для выполнения scan-запросов используется метод `table.Session.StreamExecuteScanQuery()`. +Если ожидаемое количество данных от запроса велико, не следует пытаться загружать их полностью в оперативную память с помощью вспомогательных методов клиента Query-сервиса, таких как `query.Client.Query` и `query.Client.QueryResultSet`. Данные вспомогательные методы реализуют внутренние повторные попытки и отдают уже материализованный результат. При большом количестве возвращаемых строк материализация результата может привести к известной проблеме "OOM killed". + +Для запросов, предполагающих большое количество данных, следует пользоваться методами сессии YDB `query.Session.Query` или `query.Session.QueryResultSet`, которые отдают "потоковый" результат без материализации. Важно отметить, что сессия `query.Session` доступна только из метода `query.Client.Do`, реализующего механизмы выполнения повторных попыток при ошибках. Соответственно, необходимо учитывать, что чтение может быть прервано в любой момент, и в таком случае весь процесс выполнения запроса начнётся заново. ```go -var ( - query = ` - DECLARE $series AS List; - SELECT series_id, season_id, title, first_aired - FROM seasons - WHERE series_id IN $series - ` - res result.StreamResult -) -err = c.Do(ctx, - func(ctx context.Context, s table.Session) (err error) { - res, err = s.StreamExecuteScanQuery(ctx, query, - table.NewQueryParameters( - table.ValueParam("$series", - types.ListValue( - types.Uint64Value(1), - types.Uint64Value(10), - ), - ), - ), - ) - if err != nil { - return err - } - defer res.Close() // закрытие result'а обязательно - var ( - seriesID uint64 - seasonID uint64 - title string - date time.Time - ) - log.Print("\n> scan_query_select:") - for res.NextResultSet(ctx) { - if err = res.Err(); err != nil { - return err - } - for res.NextRow() { - // named.OptionalWithDefault позволяет "развернуть" опциональные - // результаты или использовать дефолтное значение типа go - err = res.ScanNamed( - named.Required("series_id", &seriesID), - named.OptionalWithDefault("season_id", &seasonID), - named.OptionalWithDefault("title", &title), - named.OptionalWithDefault("first_aired", &date), - ) - if err != nil { - return err - } - log.Printf("# Season, SeriesId: %d, SeasonId: %d, Title: %s, Air date: %s", seriesID, seasonID, title, date) - } - } - return res.Err() - }, +err = db.Query().Do(ctx, + func(ctx context.Context, s query.Session) error { + rows, err := s.QueryResultSet(ctx,` + SELECT series_id, season_id, title, first_aired + FROM seasons`, + ) + if err != nil { + return err + } + defer rows.Close(ctx) + for row, err := range rows.Rows(ctx) { + if err != nil { + return err + } + var info struct { + SeriesID string `sql:"series_id"` + SeasonID string `sql:"season_id"` + Title string `sql:"title"` + FirstAired time.Time `sql:"first_aired"` + } + err = row.ScanStruct(&info) + if err != nil { + return err + } + fmt.Printf("%+v\n", info) + } + return nil + }, + query.WithIdempotent(), ) if err != nil { // обработка ошибки выполнения запроса From caacee4b4d7d822de0257172888776aa5c456997 Mon Sep 17 00:00:00 2001 From: Aleksey Myasnikov Date: Tue, 8 Oct 2024 11:04:12 +0300 Subject: [PATCH 02/44] OOM killed as link to wiki --- ydb/docs/ru/core/dev/example-app/go/index.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ydb/docs/ru/core/dev/example-app/go/index.md b/ydb/docs/ru/core/dev/example-app/go/index.md index cdfae2e737ec..b8159b5f4ee8 100644 --- a/ydb/docs/ru/core/dev/example-app/go/index.md +++ b/ydb/docs/ru/core/dev/example-app/go/index.md @@ -86,8 +86,8 @@ defer db.Close(ctx) * метод `db.Query().Do(ctx, op)` реализует фоновое создание сессий и повторные попытки выполнить пользовательскую операцию `op func(ctx context.Context, s query.Session) error`, в которую пользовательскому коду отдается подготовленная сессия `query.Session`. * метод `db.Query().DoTx(ctx, op)` принимает пользовательскую операцию `op func(ctx context.Context, tx query.TxActor) error`, в которую пользовательскому коду отдается подготовленная (заранее открытая) транзакция `query.TxActor`. `Commit` транзакции также автоматический, если из пользовательской операции возвращается `nil`. В случае, если из пользовательской операции возвращается ошибка, то для текущей транзакции автоматически будет вызван `Rollback`. * метод `db.Query().Exec` является вспомогательным и предназначен для выполнения единичного запроса **без результата** с автоматическими повторными попытками. Метод `Exec` возвращает `nil` в случае успешного выполнения запроса и ошибку, если операция не удалась. -* метод `db.Query().Query` является вспомогательным и предназначен для выполнения единичного запроса с автоматическими повторными попытками внутри. Метод `Query` возвращает в случае успеха материализованный результат запроса `query.Result`. `query.Result` позволяет итерироваться по вложенным спискам строк `query.ResultSet`. Для широких SQL-запросов, возвращающих большое количество строк, материализация результата может привести к проблеме `OOM killed`. -* метод `db.Query().QueryResultSet` является вспомогательным и предназначен для выполнения единичного запроса с автоматическими повторными попытками внутри. Метод `QueryResultSet` возвращает в случае успеха материализованный список строк `query.ResultSet`. Для широких SQL-запросов, возвращающих большое количество строк, материализация результата может привести к проблеме `OOM killed`. +* метод `db.Query().Query` является вспомогательным и предназначен для выполнения единичного запроса с автоматическими повторными попытками внутри. Метод `Query` возвращает в случае успеха материализованный результат запроса `query.Result`, позволяет итерироваться по вложенным спискам строк `query.ResultSet`. Для широких SQL-запросов, возвращающих большое количество строк, материализация результата может привести к проблеме [OOM killed](https://en.wikipedia.org/wiki/Out_of_memory). +* метод `db.Query().QueryResultSet` является вспомогательным и предназначен для выполнения единичного запроса с автоматическими повторными попытками внутри. Метод `QueryResultSet` возвращает в случае успеха материализованный список строк `query.ResultSet`. Для широких SQL-запросов, возвращающих большое количество строк, материализация результата может привести к проблеме [OOM killed](https://en.wikipedia.org/wiki/Out_of_memory). * метод `db.Query().QueryRow` является вспомогательным и предназначен для выполнения единичного запроса с автоматическими повторными попытками внутри. Метод `QueryRow` возвращает в случае успеха единственную строку `query.Row`. {% include [steps/02_create_table.md](../_includes/steps/02_create_table.md) %} From 6f32cfb902566bb2d46bab7f61a4c52a6fb76bcb Mon Sep 17 00:00:00 2001 From: Aleksey Myasnikov Date: Fri, 6 Dec 2024 13:37:51 +0300 Subject: [PATCH 03/44] Apply suggestions from code review Co-authored-by: Timofey Koolin --- ydb/docs/ru/core/dev/example-app/go/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ydb/docs/ru/core/dev/example-app/go/index.md b/ydb/docs/ru/core/dev/example-app/go/index.md index b8159b5f4ee8..384dc870ff0e 100644 --- a/ydb/docs/ru/core/dev/example-app/go/index.md +++ b/ydb/docs/ru/core/dev/example-app/go/index.md @@ -87,7 +87,7 @@ defer db.Close(ctx) * метод `db.Query().DoTx(ctx, op)` принимает пользовательскую операцию `op func(ctx context.Context, tx query.TxActor) error`, в которую пользовательскому коду отдается подготовленная (заранее открытая) транзакция `query.TxActor`. `Commit` транзакции также автоматический, если из пользовательской операции возвращается `nil`. В случае, если из пользовательской операции возвращается ошибка, то для текущей транзакции автоматически будет вызван `Rollback`. * метод `db.Query().Exec` является вспомогательным и предназначен для выполнения единичного запроса **без результата** с автоматическими повторными попытками. Метод `Exec` возвращает `nil` в случае успешного выполнения запроса и ошибку, если операция не удалась. * метод `db.Query().Query` является вспомогательным и предназначен для выполнения единичного запроса с автоматическими повторными попытками внутри. Метод `Query` возвращает в случае успеха материализованный результат запроса `query.Result`, позволяет итерироваться по вложенным спискам строк `query.ResultSet`. Для широких SQL-запросов, возвращающих большое количество строк, материализация результата может привести к проблеме [OOM killed](https://en.wikipedia.org/wiki/Out_of_memory). -* метод `db.Query().QueryResultSet` является вспомогательным и предназначен для выполнения единичного запроса с автоматическими повторными попытками внутри. Метод `QueryResultSet` возвращает в случае успеха материализованный список строк `query.ResultSet`. Для широких SQL-запросов, возвращающих большое количество строк, материализация результата может привести к проблеме [OOM killed](https://en.wikipedia.org/wiki/Out_of_memory). +* метод `db.Query().QueryResultSet` является вспомогательным и предназначен для выполнения единичного запроса с автоматическими повторными попытками внутри. Метод `QueryResultSet` возвращает в случае успеха материализованный список результатов `query.ResultSet`. Для широких SQL-запросов, возвращающих большое количество строк, материализация результата может привести к проблеме [OOM killed](https://en.wikipedia.org/wiki/Out_of_memory). * метод `db.Query().QueryRow` является вспомогательным и предназначен для выполнения единичного запроса с автоматическими повторными попытками внутри. Метод `QueryRow` возвращает в случае успеха единственную строку `query.Row`. {% include [steps/02_create_table.md](../_includes/steps/02_create_table.md) %} From 45568b5205d689c3c6a785234e7a36ab54793d7e Mon Sep 17 00:00:00 2001 From: Timofey Koolin Date: Thu, 16 Jan 2025 09:02:50 +0000 Subject: [PATCH 04/44] some style and typos --- .../example-app/go/_includes/run_docker.md | 6 ----- ydb/docs/ru/core/dev/example-app/go/index.md | 23 +++++++++++-------- 2 files changed, 13 insertions(+), 16 deletions(-) diff --git a/ydb/docs/ru/core/dev/example-app/go/_includes/run_docker.md b/ydb/docs/ru/core/dev/example-app/go/_includes/run_docker.md index f1f98a401074..5833f36fd57a 100644 --- a/ydb/docs/ru/core/dev/example-app/go/_includes/run_docker.md +++ b/ydb/docs/ru/core/dev/example-app/go/_includes/run_docker.md @@ -1,12 +1,6 @@ Для соединения с развернутой локальной базой данных {{ ydb-short-name }} по сценарию [Docker](../../../../quickstart.md) в конфигурации по умолчанию выполните следующую команду: -<<<<<<< HEAD ``` bash ( export YDB_ANONYMOUS_CREDENTIALS=1 && cd ydb-go-sdk/examples && \ go run ./basic/native/query -ydb="grpc://localhost:2136/local" ) -======= -```bash -( export YDB_ANONYMOUS_CREDENTIALS=1 && cd ydb-go-examples && \ -go run ./basic -ydb="grpc://localhost:2136?database=/local" ) ->>>>>>> main ``` diff --git a/ydb/docs/ru/core/dev/example-app/go/index.md b/ydb/docs/ru/core/dev/example-app/go/index.md index 7efd10a98260..207592c7811a 100644 --- a/ydb/docs/ru/core/dev/example-app/go/index.md +++ b/ydb/docs/ru/core/dev/example-app/go/index.md @@ -40,6 +40,9 @@ db, err := ydb.Open(context.Background(), "grpc://localhost:2136/local") if err != nil { // обработка ошибки подключения } + +// При заверщении работы с базой (например выходе из программы) - закройте драйвер +defer db.Close(context.Backgroung()) ``` Метод `ydb.Open` возвращает в случае успеха экземпляр драйвера, которые выполняет ряд служебных функций, таких как актуализация сведений о кластере YDB и клиентская балансировка. @@ -51,7 +54,7 @@ if err != nil { Также доступно множество опций подключения, позволяющих переопределить значения по умолчанию. -Так, по умолчанию используется анонимная авторизация. А для подключения к кластеру YDB с использованием токена авторизации будет иметь вид: +По умолчанию используется анонимная авторизация. А для подключения к кластеру YDB с использованием токена авторизации будет иметь вид: ```go db, err := ydb.Open(context.Background(), clusterEndpoint, @@ -86,17 +89,17 @@ defer db.Close(ctx) * метод `db.Query().Do(ctx, op)` реализует фоновое создание сессий и повторные попытки выполнить пользовательскую операцию `op func(ctx context.Context, s query.Session) error`, в которую пользовательскому коду отдается подготовленная сессия `query.Session`. * метод `db.Query().DoTx(ctx, op)` принимает пользовательскую операцию `op func(ctx context.Context, tx query.TxActor) error`, в которую пользовательскому коду отдается подготовленная (заранее открытая) транзакция `query.TxActor`. `Commit` транзакции также автоматический, если из пользовательской операции возвращается `nil`. В случае, если из пользовательской операции возвращается ошибка, то для текущей транзакции автоматически будет вызван `Rollback`. * метод `db.Query().Exec` является вспомогательным и предназначен для выполнения единичного запроса **без результата** с автоматическими повторными попытками. Метод `Exec` возвращает `nil` в случае успешного выполнения запроса и ошибку, если операция не удалась. -* метод `db.Query().Query` является вспомогательным и предназначен для выполнения единичного запроса с автоматическими повторными попытками внутри. Метод `Query` возвращает в случае успеха материализованный результат запроса `query.Result`, позволяет итерироваться по вложенным спискам строк `query.ResultSet`. Для широких SQL-запросов, возвращающих большое количество строк, материализация результата может привести к проблеме [OOM killed](https://en.wikipedia.org/wiki/Out_of_memory). -* метод `db.Query().QueryResultSet` является вспомогательным и предназначен для выполнения единичного запроса с автоматическими повторными попытками внутри. Метод `QueryResultSet` возвращает в случае успеха материализованный список результатов `query.ResultSet`. Для широких SQL-запросов, возвращающих большое количество строк, материализация результата может привести к проблеме [OOM killed](https://en.wikipedia.org/wiki/Out_of_memory). -* метод `db.Query().QueryRow` является вспомогательным и предназначен для выполнения единичного запроса с автоматическими повторными попытками внутри. Метод `QueryRow` возвращает в случае успеха единственную строку `query.Row`. +* метод `db.Query().Query` является вспомогательным и предназначен для выполнения единичного запроса, с повторными попытками при необходимости. Текст запроса может содержать несколько выражений с результатами. Метод `Query` возвращает в случае успеха материализованный результат запроса (все данные уже прочитаны с сервера и доступны из локальной памяти) `query.Result`, позволяет итерироваться по вложенным спискам строк `query.ResultSet`. Для широких SQL-запросов, возвращающих большое количество строк, материализация результата может привести к проблеме [OOM killed](https://en.wikipedia.org/wiki/Out_of_memory). +* метод `db.Query().QueryResultSet` является вспомогательным и предназначен для выполнения единичного запроса, с повторными попытками при необходимости. В запросе должно быть ровно одно выражение, возвращающее результат (дополнительно могут присутствовать выражения, не возвращающие результат - например `UPSERT`). Метод `QueryResultSet` возвращает в случае успеха материализованный список результатов `query.ResultSet`. Для широких SQL-запросов, возвращающих большое количество строк, материализация результата может привести к проблеме [OOM killed](https://en.wikipedia.org/wiki/Out_of_memory). +* метод `db.Query().QueryRow` является вспомогательным и предназначен для выполнения единичного запроса, с повторными попытками при необходимости. Метод `QueryRow` возвращает в случае успеха единственную строку `query.Row`. {% include [steps/02_create_table.md](../_includes/steps/02_create_table.md) %} -Пример создания таблицы: +Пример создания таблицы (запрос без возвращаемого результата): ```go import "github.com/ydb-platform/ydb-go-sdk/v3/query" -//////////////////////////////////////////////////// + err = db.Query().Exec(ctx, ` CREATE TABLE IF NOT EXISTS series ( series_id Bytes, @@ -115,7 +118,7 @@ if err != nil { {% include [steps/04_query_processing.md](../_includes/steps/04_query_processing.md) %} -Для выполнения YQL-запросов без результата `query.Result` используется метод `query.Session.Exec`. Для выполнения YQL-запросов c результатом используется методы `query.Session.Query`, `query.Session.QueryResultSet` и `query.Session.QueryRow`. +Для выполнения YQL-запросов и чтения результатов используется методы `query.Session.Query`, `query.Session.QueryResultSet` и `query.Session.QueryRow`. SDK позволяет в явном виде контролировать выполнение транзакций и настраивать необходимый режим выполнения транзакций с помощью структуры `query.TxControl`. @@ -146,7 +149,7 @@ if err != nil { } ``` -Чтобы вычитать данные строки YDB `query.Row` используются методы `query.Row.Scan` (по индексу колонки), `query.Row.ScanNamed` (по названию колонки) и `query.Row.ScanStruct` (по названиям колонок, зафиксированных к тегах структуры): +Чтобы вычитать данные строки YDB `query.Row` используются методы `query.Row.Scan` (по порядку колонок), `query.Row.ScanNamed` (по названию колонки) и `query.Row.ScanStruct` (по названиям колонок, зафиксированных к тегах структуры): ```go var info struct { @@ -162,9 +165,9 @@ if err != nil { {% include [scan_query.md](../_includes/steps/08_scan_query.md) %} -Если ожидаемое количество данных от запроса велико, не следует пытаться загружать их полностью в оперативную память с помощью вспомогательных методов клиента Query-сервиса, таких как `query.Client.Query` и `query.Client.QueryResultSet`. Данные вспомогательные методы реализуют внутренние повторные попытки и отдают уже материализованный результат. При большом количестве возвращаемых строк материализация результата может привести к известной проблеме "OOM killed". +Если ожидаемое количество данных от запроса велико, не следует пытаться загружать их полностью в оперативную память с помощью вспомогательных методов клиента Query-сервиса, таких как `query.Client.Query` и `query.Client.QueryResultSet`. Эти методы отдают уже материализованный результат (весь результат запроса прочитан с сервера в локальную память). При большом количестве возвращаемых строк материализация результата может привести к известной проблеме "OOM killed". -Для запросов, предполагающих большое количество данных, следует пользоваться методами сессии YDB `query.Session.Query` или `query.Session.QueryResultSet`, которые отдают "потоковый" результат без материализации. Важно отметить, что сессия `query.Session` доступна только из метода `query.Client.Do`, реализующего механизмы выполнения повторных попыток при ошибках. Соответственно, необходимо учитывать, что чтение может быть прервано в любой момент, и в таком случае весь процесс выполнения запроса начнётся заново. +Для запросов, предполагающих большое количество данных, следует пользоваться методами сессии YDB `query.TxActor.Query` или `query.TxActor.QueryResultSet`, которые отдают "потоковый" результат без материализации. Сессия `query.Session` доступна только из метода `query.Client.Do`, реализующего механизмы выполнения повторных попыток при ошибках. Нужно учитывать, что чтение может быть прервано в любой момент, и в таком случае весь процесс выполнения запроса начнётся заново. Т.е. функция, переданная в `Do` может вызываться больше одного раза. ```go err = db.Query().Do(ctx, From 4601105fa068d0d49441f6bce93e173947746cc9 Mon Sep 17 00:00:00 2001 From: Timofey Koolin Date: Thu, 16 Jan 2025 09:28:51 +0000 Subject: [PATCH 05/44] style --- .../ru/core/dev/example-app/go/_includes/run_custom.md | 10 ++-------- ydb/docs/ru/core/dev/example-app/go/index.md | 8 ++++---- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/ydb/docs/ru/core/dev/example-app/go/_includes/run_custom.md b/ydb/docs/ru/core/dev/example-app/go/_includes/run_custom.md index 769c8c81b92b..f436592fb4f8 100644 --- a/ydb/docs/ru/core/dev/example-app/go/_includes/run_custom.md +++ b/ydb/docs/ru/core/dev/example-app/go/_includes/run_custom.md @@ -4,15 +4,9 @@ Выполните команду по следующему образцу: -<<<<<<< HEAD -``` bash -( export ="" && cd ydb-go-sdk/examples && \ -go run . -ydb="/" ) -======= ```bash -( export ="" && cd ydb-go-examples && \ +( export ="" && cd ydb-go-sdk/examples && \ go run ./basic -ydb="?database=" ) ->>>>>>> main ``` где @@ -25,6 +19,6 @@ go run ./basic -ydb="?database=" ) Например: ```bash -( export YDB_ACCESS_TOKEN_CREDENTIALS="t1.9euelZqOnJuJlc..." && cd ydb-go-examples && \ +( export YDB_ACCESS_TOKEN_CREDENTIALS="t1.9euelZqOnJuJlc..." && cd ydb-go-sdk/examples && \ go run ./basic -ydb="grpcs://ydb.example.com:2135/somepath/somelocation" ) ``` diff --git a/ydb/docs/ru/core/dev/example-app/go/index.md b/ydb/docs/ru/core/dev/example-app/go/index.md index 207592c7811a..1cabd0cf618e 100644 --- a/ydb/docs/ru/core/dev/example-app/go/index.md +++ b/ydb/docs/ru/core/dev/example-app/go/index.md @@ -11,7 +11,7 @@ Создайте рабочую директорию и выполните в ней из командной строки команду клонирования репозитория с GitHub: ``` bash -git clone git@github.com:ydb-platform/ydb-go-sdk.git +git clone https://github.com/ydb-platform/ydb-go-sdk.git ``` Далее из этой же рабочей директории выполните команду запуска тестового приложения, которая будет отличаться в зависимости от того, к какой базе данных необходимо подключиться. @@ -82,7 +82,7 @@ defer db.Close(ctx) * `db.Scheme()` - клиент scheme-сервиса * `db.Operation()` - клиент operation-сервиса -Для работы таблицами YDB следует использовать клиента query-сервиса `db.Query()`. Выполнение `DDL`, `DML`, `DQL` и `TCL` запросов в таблицы YDB осуществляется на специальных объекта - сессиях `query.Session`. Сессии YDB хранят контекст выполнения запросов (например, Prepared statements и транзакции) и позволяют осуществлять серверную балансировать балансировку нагрузки на узлы кластера YDB. +Для работы таблицами YDB следует использовать клиента query-сервиса `db.Query()`. Выполнение запросов в таблицы YDB осуществляется на специальных объектах - сессиях `query.Session`. Сессии YDB хранят контекст выполнения запросов (например, Prepared statements и транзакции) и позволяют осуществлять серверную балансировать балансировку нагрузки на узлы кластера YDB. Клиент query-сервиса предоставляет `API` для выполнения запросов над таблицами: @@ -149,7 +149,7 @@ if err != nil { } ``` -Чтобы вычитать данные строки YDB `query.Row` используются методы `query.Row.Scan` (по порядку колонок), `query.Row.ScanNamed` (по названию колонки) и `query.Row.ScanStruct` (по названиям колонок, зафиксированных к тегах структуры): +Чтобы вычитать данные строки YDB `query.Row` используются методы `query.Row.Scan` (по порядку колонок), `query.Row.ScanNamed` (по названию колонки) или `query.Row.ScanStruct` (по названиям колонок, зафиксированных к тегах структуры): ```go var info struct { @@ -165,7 +165,7 @@ if err != nil { {% include [scan_query.md](../_includes/steps/08_scan_query.md) %} -Если ожидаемое количество данных от запроса велико, не следует пытаться загружать их полностью в оперативную память с помощью вспомогательных методов клиента Query-сервиса, таких как `query.Client.Query` и `query.Client.QueryResultSet`. Эти методы отдают уже материализованный результат (весь результат запроса прочитан с сервера в локальную память). При большом количестве возвращаемых строк материализация результата может привести к известной проблеме "OOM killed". +Если ожидаемое количество данных от запроса велико, не следует пытаться загружать их полностью в оперативную память с помощью вспомогательных методов клиента Query-сервиса, таких как `query.Client.Query` и `query.Client.QueryResultSet`. Эти методы отдают уже материализованный результат (весь результат запроса прочитан с сервера в локальную память). При большом количестве возвращаемых строк материализация результата может привести к известной проблеме [OOM killed](https://en.wikipedia.org/wiki/Out_of_memory). Для запросов, предполагающих большое количество данных, следует пользоваться методами сессии YDB `query.TxActor.Query` или `query.TxActor.QueryResultSet`, которые отдают "потоковый" результат без материализации. Сессия `query.Session` доступна только из метода `query.Client.Do`, реализующего механизмы выполнения повторных попыток при ошибках. Нужно учитывать, что чтение может быть прервано в любой момент, и в таком случае весь процесс выполнения запроса начнётся заново. Т.е. функция, переданная в `Do` может вызываться больше одного раза. From cdd8ad62b3c8e7e0afed7dab09152d266ef3f97d Mon Sep 17 00:00:00 2001 From: Timofey Koolin Date: Tue, 21 Jan 2025 20:18:55 +0300 Subject: [PATCH 06/44] Update ydb/docs/ru/core/dev/example-app/go/index.md Co-authored-by: Ivan Blinkov --- ydb/docs/ru/core/dev/example-app/go/index.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ydb/docs/ru/core/dev/example-app/go/index.md b/ydb/docs/ru/core/dev/example-app/go/index.md index 1cabd0cf618e..f990b085a905 100644 --- a/ydb/docs/ru/core/dev/example-app/go/index.md +++ b/ydb/docs/ru/core/dev/example-app/go/index.md @@ -165,9 +165,9 @@ if err != nil { {% include [scan_query.md](../_includes/steps/08_scan_query.md) %} -Если ожидаемое количество данных от запроса велико, не следует пытаться загружать их полностью в оперативную память с помощью вспомогательных методов клиента Query-сервиса, таких как `query.Client.Query` и `query.Client.QueryResultSet`. Эти методы отдают уже материализованный результат (весь результат запроса прочитан с сервера в локальную память). При большом количестве возвращаемых строк материализация результата может привести к известной проблеме [OOM killed](https://en.wikipedia.org/wiki/Out_of_memory). +Если ожидаемый объём данных от запроса велик, не следует пытаться загружать их полностью в оперативную память с помощью вспомогательных методов, таких как `query.Client.Query` и `query.Client.QueryResultSet`. Эти методы отдают уже материализованный результат, где весь результат запроса уже прочитан с сервера в локальную память клиентского приложения. При большом количестве возвращаемых строк материализация результата может привести к проблеме [OOM](https://en.wikipedia.org/wiki/Out_of_memory). -Для запросов, предполагающих большое количество данных, следует пользоваться методами сессии YDB `query.TxActor.Query` или `query.TxActor.QueryResultSet`, которые отдают "потоковый" результат без материализации. Сессия `query.Session` доступна только из метода `query.Client.Do`, реализующего механизмы выполнения повторных попыток при ошибках. Нужно учитывать, что чтение может быть прервано в любой момент, и в таком случае весь процесс выполнения запроса начнётся заново. Т.е. функция, переданная в `Do` может вызываться больше одного раза. +Для таких запросов следует пользоваться методами сессии `query.TxActor.Query` или `query.TxActor.QueryResultSet`, которые отдают итератор по результату без полной материализации. Сессия `query.Session` доступна только из метода `query.Client.Do`, реализующего механизмы выполнения повторных попыток при ошибках. Нужно учитывать, что чтение может быть прервано в любой момент, и в таком случае весь процесс выполнения запроса начнётся заново. То есть функция, переданная в `Do`, может вызываться больше одного раза. ```go err = db.Query().Do(ctx, From 4873a4b28b376f2633681da5f7ab688b8194a2c0 Mon Sep 17 00:00:00 2001 From: Timofey Koolin Date: Tue, 21 Jan 2025 20:19:26 +0300 Subject: [PATCH 07/44] Update ydb/docs/ru/core/dev/example-app/go/index.md Co-authored-by: Ivan Blinkov --- ydb/docs/ru/core/dev/example-app/go/index.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ydb/docs/ru/core/dev/example-app/go/index.md b/ydb/docs/ru/core/dev/example-app/go/index.md index f990b085a905..7b7294fa0380 100644 --- a/ydb/docs/ru/core/dev/example-app/go/index.md +++ b/ydb/docs/ru/core/dev/example-app/go/index.md @@ -149,7 +149,11 @@ if err != nil { } ``` -Чтобы вычитать данные строки YDB `query.Row` используются методы `query.Row.Scan` (по порядку колонок), `query.Row.ScanNamed` (по названию колонки) или `query.Row.ScanStruct` (по названиям колонок, зафиксированных к тегах структуры): +Для получения данных строки `query.Row` можно использовать следующие методы: + +* `query.Row.Scan` — по порядку колонок; +* `query.Row.ScanNamed` — по названиям колонок; +* `query.Row.ScanStruct` — по названиям колонок, зафиксированным в тегах структуры. ```go var info struct { From 4202168103ea948990faf3af644c6e7dba47a209 Mon Sep 17 00:00:00 2001 From: Timofey Koolin Date: Tue, 21 Jan 2025 20:20:07 +0300 Subject: [PATCH 08/44] Update ydb/docs/ru/core/dev/example-app/go/index.md Co-authored-by: Ivan Blinkov --- ydb/docs/ru/core/dev/example-app/go/index.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ydb/docs/ru/core/dev/example-app/go/index.md b/ydb/docs/ru/core/dev/example-app/go/index.md index 7b7294fa0380..c0d26f31ad45 100644 --- a/ydb/docs/ru/core/dev/example-app/go/index.md +++ b/ydb/docs/ru/core/dev/example-app/go/index.md @@ -86,12 +86,12 @@ defer db.Close(ctx) Клиент query-сервиса предоставляет `API` для выполнения запросов над таблицами: -* метод `db.Query().Do(ctx, op)` реализует фоновое создание сессий и повторные попытки выполнить пользовательскую операцию `op func(ctx context.Context, s query.Session) error`, в которую пользовательскому коду отдается подготовленная сессия `query.Session`. -* метод `db.Query().DoTx(ctx, op)` принимает пользовательскую операцию `op func(ctx context.Context, tx query.TxActor) error`, в которую пользовательскому коду отдается подготовленная (заранее открытая) транзакция `query.TxActor`. `Commit` транзакции также автоматический, если из пользовательской операции возвращается `nil`. В случае, если из пользовательской операции возвращается ошибка, то для текущей транзакции автоматически будет вызван `Rollback`. -* метод `db.Query().Exec` является вспомогательным и предназначен для выполнения единичного запроса **без результата** с автоматическими повторными попытками. Метод `Exec` возвращает `nil` в случае успешного выполнения запроса и ошибку, если операция не удалась. -* метод `db.Query().Query` является вспомогательным и предназначен для выполнения единичного запроса, с повторными попытками при необходимости. Текст запроса может содержать несколько выражений с результатами. Метод `Query` возвращает в случае успеха материализованный результат запроса (все данные уже прочитаны с сервера и доступны из локальной памяти) `query.Result`, позволяет итерироваться по вложенным спискам строк `query.ResultSet`. Для широких SQL-запросов, возвращающих большое количество строк, материализация результата может привести к проблеме [OOM killed](https://en.wikipedia.org/wiki/Out_of_memory). -* метод `db.Query().QueryResultSet` является вспомогательным и предназначен для выполнения единичного запроса, с повторными попытками при необходимости. В запросе должно быть ровно одно выражение, возвращающее результат (дополнительно могут присутствовать выражения, не возвращающие результат - например `UPSERT`). Метод `QueryResultSet` возвращает в случае успеха материализованный список результатов `query.ResultSet`. Для широких SQL-запросов, возвращающих большое количество строк, материализация результата может привести к проблеме [OOM killed](https://en.wikipedia.org/wiki/Out_of_memory). -* метод `db.Query().QueryRow` является вспомогательным и предназначен для выполнения единичного запроса, с повторными попытками при необходимости. Метод `QueryRow` возвращает в случае успеха единственную строку `query.Row`. +* Метод `db.Query().Do(ctx, op)` реализует фоновое создание сессий и повторные попытки выполнить пользовательскую операцию `op func(ctx context.Context, s query.Session) error`, в которую пользовательскому коду передаётся подготовленная сессия `query.Session`. +* Метод `db.Query().DoTx(ctx, op)` принимает пользовательскую операцию `op func(ctx context.Context, tx query.TxActor) error`, в которую пользовательскому коду передаётся подготовленная (заранее открытая) транзакция `query.TxActor`. Автоматическое выполнение `Commit` транзакции происходит, если из пользовательской операции возвращается `nil`. В случае возврата ошибки из пользовательской операции для текущей транзакции автоматически вызывается `Rollback`. +* Метод `db.Query().Exec` является вспомогательным и предназначен для выполнения единичного запроса **без результата** с автоматическими повторными попытками. Метод `Exec` возвращает `nil` в случае успешного выполнения запроса и ошибку, если операция не удалась. +* Метод `db.Query().Query` является вспомогательным и предназначен для выполнения единичного запроса с повторными попытками при необходимости. Текст запроса может содержать несколько выражений с результатами. Метод `Query` возвращает, в случае успеха, материализованный результат запроса (все данные уже прочитаны с сервера и доступны из локальной памяти) `query.Result` и позволяет итерироваться по вложенным спискам строк `query.ResultSet`. Для широких SQL-запросов, возвращающих большое количество строк, материализация результата может привести к проблеме [OOM](https://en.wikipedia.org/wiki/Out_of_memory). +* Метод `db.Query().QueryResultSet` является вспомогательным и предназначен для выполнения единичного запроса с повторными попытками при необходимости. В запросе должно быть ровно одно выражение, возвращающее результат (дополнительно могут присутствовать выражения, не возвращающие результат, например `UPSERT`). Метод `QueryResultSet` возвращает, в случае успеха, материализованный список результатов `query.ResultSet`. Для широких SQL-запросов, возвращающих большое количество строк, материализация результата может привести к проблеме [OOM](https://en.wikipedia.org/wiki/Out_of_memory). +* Метод `db.Query().QueryRow` является вспомогательным и предназначен для выполнения единичного запроса с повторными попытками при необходимости. Метод `QueryRow` возвращает, в случае успеха, единственную строку `query.Row`. {% include [steps/02_create_table.md](../_includes/steps/02_create_table.md) %} From 836ab3ac746da9593e28694c974f15ea4e405327 Mon Sep 17 00:00:00 2001 From: Timofey Koolin Date: Tue, 21 Jan 2025 20:22:00 +0300 Subject: [PATCH 09/44] Update ydb/docs/ru/core/dev/example-app/go/index.md Co-authored-by: Ivan Blinkov --- ydb/docs/ru/core/dev/example-app/go/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ydb/docs/ru/core/dev/example-app/go/index.md b/ydb/docs/ru/core/dev/example-app/go/index.md index c0d26f31ad45..18ddc7f11769 100644 --- a/ydb/docs/ru/core/dev/example-app/go/index.md +++ b/ydb/docs/ru/core/dev/example-app/go/index.md @@ -82,7 +82,7 @@ defer db.Close(ctx) * `db.Scheme()` - клиент scheme-сервиса * `db.Operation()` - клиент operation-сервиса -Для работы таблицами YDB следует использовать клиента query-сервиса `db.Query()`. Выполнение запросов в таблицы YDB осуществляется на специальных объектах - сессиях `query.Session`. Сессии YDB хранят контекст выполнения запросов (например, Prepared statements и транзакции) и позволяют осуществлять серверную балансировать балансировку нагрузки на узлы кластера YDB. +Выполнение YQL-запросов осуществляется на специальных объектах — сессиях `query.Session`. Сессии хранят контекст выполнения запросов (например, prepared statements и транзакции) и позволяют осуществлять серверную балансировку нагрузки на узлы кластера {{ ydb-short-name }}. Клиент query-сервиса предоставляет `API` для выполнения запросов над таблицами: From 64dd7d648957dee845797318d8fc5b2219180ef6 Mon Sep 17 00:00:00 2001 From: Timofey Koolin Date: Tue, 21 Jan 2025 20:23:55 +0300 Subject: [PATCH 10/44] Update ydb/docs/ru/core/dev/example-app/go/index.md Co-authored-by: Ivan Blinkov --- ydb/docs/ru/core/dev/example-app/go/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ydb/docs/ru/core/dev/example-app/go/index.md b/ydb/docs/ru/core/dev/example-app/go/index.md index 18ddc7f11769..81c9b662fcd5 100644 --- a/ydb/docs/ru/core/dev/example-app/go/index.md +++ b/ydb/docs/ru/core/dev/example-app/go/index.md @@ -50,7 +50,7 @@ defer db.Close(context.Backgroung()) Метод `ydb.Open` принимает 2 обязательных аргемента: * контекст -* строка подключения к YDB. +* строка подключения к {{ ydb-short-name }}. Также доступно множество опций подключения, позволяющих переопределить значения по умолчанию. From 5a88c66ea85daaf39149fbb53ac310ed80703212 Mon Sep 17 00:00:00 2001 From: Timofey Koolin Date: Tue, 21 Jan 2025 20:24:23 +0300 Subject: [PATCH 11/44] Update ydb/docs/ru/core/dev/example-app/go/index.md Co-authored-by: Ivan Blinkov --- ydb/docs/ru/core/dev/example-app/go/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ydb/docs/ru/core/dev/example-app/go/index.md b/ydb/docs/ru/core/dev/example-app/go/index.md index 81c9b662fcd5..133d64398371 100644 --- a/ydb/docs/ru/core/dev/example-app/go/index.md +++ b/ydb/docs/ru/core/dev/example-app/go/index.md @@ -45,7 +45,7 @@ if err != nil { defer db.Close(context.Backgroung()) ``` -Метод `ydb.Open` возвращает в случае успеха экземпляр драйвера, которые выполняет ряд служебных функций, таких как актуализация сведений о кластере YDB и клиентская балансировка. +Метод `ydb.Open` возвращает в случае успеха экземпляр драйвера, которые выполняет ряд служебных функций, таких как актуализация сведений о кластере {{ ydb-short-name }} и клиентская балансировка. Метод `ydb.Open` принимает 2 обязательных аргемента: From 9e0c525767c808bfd2902866785b4a3a47c9b1d4 Mon Sep 17 00:00:00 2001 From: Timofey Koolin Date: Tue, 21 Jan 2025 20:24:36 +0300 Subject: [PATCH 12/44] Update ydb/docs/ru/core/dev/example-app/go/index.md Co-authored-by: anton-bobkov --- ydb/docs/ru/core/dev/example-app/go/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ydb/docs/ru/core/dev/example-app/go/index.md b/ydb/docs/ru/core/dev/example-app/go/index.md index 133d64398371..9fb11a946768 100644 --- a/ydb/docs/ru/core/dev/example-app/go/index.md +++ b/ydb/docs/ru/core/dev/example-app/go/index.md @@ -47,7 +47,7 @@ defer db.Close(context.Backgroung()) Метод `ydb.Open` возвращает в случае успеха экземпляр драйвера, которые выполняет ряд служебных функций, таких как актуализация сведений о кластере {{ ydb-short-name }} и клиентская балансировка. -Метод `ydb.Open` принимает 2 обязательных аргемента: +Метод `ydb.Open` принимает два обязательных аргумента: * контекст * строка подключения к {{ ydb-short-name }}. From ca9a433f33a75d317d4e6407cba8547bab85052c Mon Sep 17 00:00:00 2001 From: Timofey Koolin Date: Tue, 21 Jan 2025 20:25:35 +0300 Subject: [PATCH 13/44] Update ydb/docs/ru/core/dev/example-app/go/index.md Co-authored-by: anton-bobkov --- ydb/docs/ru/core/dev/example-app/go/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ydb/docs/ru/core/dev/example-app/go/index.md b/ydb/docs/ru/core/dev/example-app/go/index.md index 9fb11a946768..1b362d9d0cee 100644 --- a/ydb/docs/ru/core/dev/example-app/go/index.md +++ b/ydb/docs/ru/core/dev/example-app/go/index.md @@ -64,7 +64,7 @@ db, err := ydb.Open(context.Background(), clusterEndpoint, Полный список провайдеров авторизации приведен в [документации ydb-go-sdk](https://github.com/ydb-platform/ydb-go-sdk?tab=readme-ov-file#credentials-) и в разделе [рецептов](../../../recipes/ydb-sdk/auth.md) -В конце работы приложения для очистки ресурсов следует закрыть драйвер +В конце работы приложения для очистки ресурсов следует закрыть драйвер: ```go defer db.Close(ctx) From 429ae0597d31896ba5ca15d6ef7ecd828d61f5d7 Mon Sep 17 00:00:00 2001 From: Timofey Koolin Date: Tue, 21 Jan 2025 20:25:46 +0300 Subject: [PATCH 14/44] Update ydb/docs/ru/core/dev/example-app/go/index.md Co-authored-by: anton-bobkov --- ydb/docs/ru/core/dev/example-app/go/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ydb/docs/ru/core/dev/example-app/go/index.md b/ydb/docs/ru/core/dev/example-app/go/index.md index 1b362d9d0cee..d5fceaa708e5 100644 --- a/ydb/docs/ru/core/dev/example-app/go/index.md +++ b/ydb/docs/ru/core/dev/example-app/go/index.md @@ -62,7 +62,7 @@ db, err := ydb.Open(context.Background(), clusterEndpoint, ) ``` -Полный список провайдеров авторизации приведен в [документации ydb-go-sdk](https://github.com/ydb-platform/ydb-go-sdk?tab=readme-ov-file#credentials-) и в разделе [рецептов](../../../recipes/ydb-sdk/auth.md) +Полный список провайдеров авторизации приведен в [документации ydb-go-sdk](https://github.com/ydb-platform/ydb-go-sdk?tab=readme-ov-file#credentials-) и в разделе [рецептов](../../../recipes/ydb-sdk/auth.md). В конце работы приложения для очистки ресурсов следует закрыть драйвер: From b1ea99a9943ea50891d9fef28611905f853261e4 Mon Sep 17 00:00:00 2001 From: Timofey Koolin Date: Tue, 21 Jan 2025 20:26:00 +0300 Subject: [PATCH 15/44] Update ydb/docs/ru/core/dev/example-app/go/index.md Co-authored-by: anton-bobkov --- ydb/docs/ru/core/dev/example-app/go/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ydb/docs/ru/core/dev/example-app/go/index.md b/ydb/docs/ru/core/dev/example-app/go/index.md index d5fceaa708e5..23abb8c9db92 100644 --- a/ydb/docs/ru/core/dev/example-app/go/index.md +++ b/ydb/docs/ru/core/dev/example-app/go/index.md @@ -54,7 +54,7 @@ defer db.Close(context.Backgroung()) Также доступно множество опций подключения, позволяющих переопределить значения по умолчанию. -По умолчанию используется анонимная авторизация. А для подключения к кластеру YDB с использованием токена авторизации будет иметь вид: +По умолчанию используется анонимная авторизация. А подключение к кластеру YDB с использованием токена авторизации будет иметь следующий вид: ```go db, err := ydb.Open(context.Background(), clusterEndpoint, From 463fd53e9aa15f57852eccce717ee27f20fd48ac Mon Sep 17 00:00:00 2001 From: Timofey Koolin Date: Tue, 21 Jan 2025 20:26:09 +0300 Subject: [PATCH 16/44] Update ydb/docs/ru/core/dev/example-app/go/index.md Co-authored-by: anton-bobkov --- ydb/docs/ru/core/dev/example-app/go/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ydb/docs/ru/core/dev/example-app/go/index.md b/ydb/docs/ru/core/dev/example-app/go/index.md index 23abb8c9db92..7f16d71190c3 100644 --- a/ydb/docs/ru/core/dev/example-app/go/index.md +++ b/ydb/docs/ru/core/dev/example-app/go/index.md @@ -49,7 +49,7 @@ defer db.Close(context.Backgroung()) Метод `ydb.Open` принимает два обязательных аргумента: -* контекст +* контекст; * строка подключения к {{ ydb-short-name }}. Также доступно множество опций подключения, позволяющих переопределить значения по умолчанию. From 607851dae4c84e6745ade6d793181ccbba30f802 Mon Sep 17 00:00:00 2001 From: Timofey Koolin Date: Tue, 21 Jan 2025 20:31:06 +0300 Subject: [PATCH 17/44] Update ydb/docs/ru/core/dev/example-app/go/index.md Co-authored-by: anton-bobkov --- ydb/docs/ru/core/dev/example-app/go/index.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/ydb/docs/ru/core/dev/example-app/go/index.md b/ydb/docs/ru/core/dev/example-app/go/index.md index 7f16d71190c3..ec93a388fa3a 100644 --- a/ydb/docs/ru/core/dev/example-app/go/index.md +++ b/ydb/docs/ru/core/dev/example-app/go/index.md @@ -72,15 +72,15 @@ defer db.Close(ctx) Объект `db` является входной точкой для работы со всеми сервисами `YDB`: -* `db.Query()` - клиент query-сервиса -* `db.Table()` - клиент table-сервиса -* `db.Discovery()` - клиент discovery-сервиса -* `db.Topic()` - клиент topic-сервиса -* `db.Coordination()` - клиент coordination-сервиса -* `db.Ratelimiter()` - клиент ratelimiter-сервиса -* `db.Scripting()` - клиент scriptingYQL-сервиса -* `db.Scheme()` - клиент scheme-сервиса -* `db.Operation()` - клиент operation-сервиса +* `db.Query()` - клиент query-сервиса; +* `db.Table()` - клиент table-сервиса; +* `db.Discovery()` - клиент discovery-сервиса; +* `db.Topic()` - клиент topic-сервиса; +* `db.Coordination()` - клиент coordination-сервиса; +* `db.Ratelimiter()` - клиент ratelimiter-сервиса; +* `db.Scripting()` - клиент scriptingYQL-сервиса; +* `db.Scheme()` - клиент scheme-сервиса; +* `db.Operation()` - клиент operation-сервиса. Выполнение YQL-запросов осуществляется на специальных объектах — сессиях `query.Session`. Сессии хранят контекст выполнения запросов (например, prepared statements и транзакции) и позволяют осуществлять серверную балансировку нагрузки на узлы кластера {{ ydb-short-name }}. From c64207f6e2852e307b20c0eb161fdfa4de4bd7f3 Mon Sep 17 00:00:00 2001 From: Timofey Koolin Date: Tue, 21 Jan 2025 20:34:28 +0300 Subject: [PATCH 18/44] Update ydb/docs/ru/core/dev/example-app/go/index.md Co-authored-by: Ivan Blinkov --- ydb/docs/ru/core/dev/example-app/go/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ydb/docs/ru/core/dev/example-app/go/index.md b/ydb/docs/ru/core/dev/example-app/go/index.md index ec93a388fa3a..91c4c512ae3b 100644 --- a/ydb/docs/ru/core/dev/example-app/go/index.md +++ b/ydb/docs/ru/core/dev/example-app/go/index.md @@ -84,7 +84,7 @@ defer db.Close(ctx) Выполнение YQL-запросов осуществляется на специальных объектах — сессиях `query.Session`. Сессии хранят контекст выполнения запросов (например, prepared statements и транзакции) и позволяют осуществлять серверную балансировку нагрузки на узлы кластера {{ ydb-short-name }}. -Клиент query-сервиса предоставляет `API` для выполнения запросов над таблицами: +Клиент предоставляет следующий API для выполнения запросов над таблицами: * Метод `db.Query().Do(ctx, op)` реализует фоновое создание сессий и повторные попытки выполнить пользовательскую операцию `op func(ctx context.Context, s query.Session) error`, в которую пользовательскому коду передаётся подготовленная сессия `query.Session`. * Метод `db.Query().DoTx(ctx, op)` принимает пользовательскую операцию `op func(ctx context.Context, tx query.TxActor) error`, в которую пользовательскому коду передаётся подготовленная (заранее открытая) транзакция `query.TxActor`. Автоматическое выполнение `Commit` транзакции происходит, если из пользовательской операции возвращается `nil`. В случае возврата ошибки из пользовательской операции для текущей транзакции автоматически вызывается `Rollback`. From d896a1b08dfda23b15e49f7c97a0c50b090c8dbe Mon Sep 17 00:00:00 2001 From: Timofey Koolin Date: Fri, 17 Jan 2025 09:35:57 +0000 Subject: [PATCH 19/44] type --- ydb/docs/ru/core/dev/example-app/go/_includes/run_custom.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ydb/docs/ru/core/dev/example-app/go/_includes/run_custom.md b/ydb/docs/ru/core/dev/example-app/go/_includes/run_custom.md index f436592fb4f8..83e5d7464568 100644 --- a/ydb/docs/ru/core/dev/example-app/go/_includes/run_custom.md +++ b/ydb/docs/ru/core/dev/example-app/go/_includes/run_custom.md @@ -13,7 +13,7 @@ go run ./basic -ydb="?database=" ) - `` - [эндпоинт](../../../../concepts/connect.md#endpoint). - `` - [путь базы данных](../../../../concepts/connect.md#database). -- ` - [переменная окружения](../../../../reference/ydb-sdk/auth.md#env), определяющая режим аутентификации. +- `` - [переменная окружения](../../../../reference/ydb-sdk/auth.md#env), определяющая режим аутентификации. - `` - значение параметра аутентификации для выбранного режима. Например: From 7b39505d65099eb75d4e3a134d40e5818c7af962 Mon Sep 17 00:00:00 2001 From: Timofey Koolin Date: Tue, 21 Jan 2025 18:44:11 +0000 Subject: [PATCH 20/44] style and by comments --- .../example-app/go/_includes/run_custom.md | 2 +- ydb/docs/ru/core/dev/example-app/go/index.md | 74 +++++++++++++++---- 2 files changed, 59 insertions(+), 17 deletions(-) diff --git a/ydb/docs/ru/core/dev/example-app/go/_includes/run_custom.md b/ydb/docs/ru/core/dev/example-app/go/_includes/run_custom.md index 83e5d7464568..f6210f2cb83e 100644 --- a/ydb/docs/ru/core/dev/example-app/go/_includes/run_custom.md +++ b/ydb/docs/ru/core/dev/example-app/go/_includes/run_custom.md @@ -1,4 +1,4 @@ -Для выполнения примера с использованием любой доступной базы данных YDB вам потребуется знать [эндпоинт](../../../../concepts/connect.md#endpoint) и [путь базы данных](../../../../concepts/connect.md#database). +Для выполнения примера с использованием любой доступной базы данных {{ ydb-short-name }} вам потребуется знать [эндпоинт](../../../../concepts/connect.md#endpoint) и [путь базы данных](../../../../concepts/connect.md#database). Если в базе данных включена аутентификация, то вам также понадобится выбрать [режим аутентификации](../../../../security/authentication.md) и получить секреты - токен или логин/пароль. diff --git a/ydb/docs/ru/core/dev/example-app/go/index.md b/ydb/docs/ru/core/dev/example-app/go/index.md index 91c4c512ae3b..239d17c644d9 100644 --- a/ydb/docs/ru/core/dev/example-app/go/index.md +++ b/ydb/docs/ru/core/dev/example-app/go/index.md @@ -33,7 +33,8 @@ import ( ) ``` -Для взаимодействия с YDB необходимо создать объект подключения к YDB: +Для взаимодействия с {{ ydb-short-name }} необходимо создать объект подключения к {{ ydb-short-name }}: + ```go db, err := ydb.Open(context.Background(), "grpc://localhost:2136/local") @@ -54,7 +55,7 @@ defer db.Close(context.Backgroung()) Также доступно множество опций подключения, позволяющих переопределить значения по умолчанию. -По умолчанию используется анонимная авторизация. А подключение к кластеру YDB с использованием токена авторизации будет иметь следующий вид: +По умолчанию используется анонимная авторизация. А подключение к кластеру {{ ydb-short-name }} с использованием токена авторизации будет иметь следующий вид: ```go db, err := ydb.Open(context.Background(), clusterEndpoint, @@ -70,6 +71,7 @@ db, err := ydb.Open(context.Background(), clusterEndpoint, defer db.Close(ctx) ``` +<<<<<<< HEAD Объект `db` является входной точкой для работы со всеми сервисами `YDB`: * `db.Query()` - клиент query-сервиса; @@ -85,6 +87,13 @@ defer db.Close(ctx) Выполнение YQL-запросов осуществляется на специальных объектах — сессиях `query.Session`. Сессии хранят контекст выполнения запросов (например, prepared statements и транзакции) и позволяют осуществлять серверную балансировку нагрузки на узлы кластера {{ ydb-short-name }}. Клиент предоставляет следующий API для выполнения запросов над таблицами: +======= +Объект `db` является входной точкой для работы со всем функционалом {{ ydb-short-name }}, для запросов к таблицам используется Query-сервис: `db.Query()`: + +Выполнение YQL-запросов осуществляется на специальных объектах — сессиях `query.Session`. Сессии хранят контекст выполнения запросов (например, prepared statements и транзакции) и позволяют осуществлять серверную балансировку нагрузки на узлы кластера {{ ydb-short-name }}. + +Клиент query-сервиса предоставляет API для выполнения запросов над таблицами: +>>>>>>> d35cd372e84 (style and by comments) * Метод `db.Query().Do(ctx, op)` реализует фоновое создание сессий и повторные попытки выполнить пользовательскую операцию `op func(ctx context.Context, s query.Session) error`, в которую пользовательскому коду передаётся подготовленная сессия `query.Session`. * Метод `db.Query().DoTx(ctx, op)` принимает пользовательскую операцию `op func(ctx context.Context, tx query.TxActor) error`, в которую пользовательскому коду передаётся подготовленная (заранее открытая) транзакция `query.TxActor`. Автоматическое выполнение `Commit` транзакции происходит, если из пользовательской операции возвращается `nil`. В случае возврата ошибки из пользовательской операции для текущей транзакции автоматически вызывается `Rollback`. @@ -151,27 +160,60 @@ if err != nil { Для получения данных строки `query.Row` можно использовать следующие методы: -* `query.Row.Scan` — по порядку колонок; -* `query.Row.ScanNamed` — по названиям колонок; * `query.Row.ScanStruct` — по названиям колонок, зафиксированным в тегах структуры. +* `query.Row.ScanNamed` — по названиям колонок. +* `query.Row.Scan` — по порядку колонок. -```go -var info struct { - SeriesID string `sql:"series_id"` - Title string `sql:"title"` - ReleaseDate time.Time `sql:"release_date"` -} -err = row.ScanStruct(&info) -if err != nil { - // обработка ошибки выполнения запроса -} -``` +{% list tabs %} + +- ScanStruct + + ```go + var info struct { + SeriesID string `sql:"series_id"` + Title string `sql:"title"` + ReleaseDate time.Time `sql:"release_date"` + } + err = row.ScanStruct(&info) + if err != nil { + // обработка ошибки выполнения запроса + } + ``` + +- ScanNamed + + ```go + var seriesID, title string + var releaseDate time.Time + err = row.ScanNamed(query.Named("series_id", &seriesID), query.Named("title", &title), query.Named("release_date", &releaseDate)) + if err != nil { + // обработка ошибки выполнения запроса + } + ``` + +- Scan + + ```go + var seriesID, title string + var releaseDate time.Time + err = row.Scan(&seriesID, &title, &releaseDate) + if err != nil { + // обработка ошибки выполнения запроса + } + ``` + +- {% endlist %} {% include [scan_query.md](../_includes/steps/08_scan_query.md) %} +{% note warning %} + Если ожидаемый объём данных от запроса велик, не следует пытаться загружать их полностью в оперативную память с помощью вспомогательных методов, таких как `query.Client.Query` и `query.Client.QueryResultSet`. Эти методы отдают уже материализованный результат, где весь результат запроса уже прочитан с сервера в локальную память клиентского приложения. При большом количестве возвращаемых строк материализация результата может привести к проблеме [OOM](https://en.wikipedia.org/wiki/Out_of_memory). -Для таких запросов следует пользоваться методами сессии `query.TxActor.Query` или `query.TxActor.QueryResultSet`, которые отдают итератор по результату без полной материализации. Сессия `query.Session` доступна только из метода `query.Client.Do`, реализующего механизмы выполнения повторных попыток при ошибках. Нужно учитывать, что чтение может быть прервано в любой момент, и в таком случае весь процесс выполнения запроса начнётся заново. То есть функция, переданная в `Do`, может вызываться больше одного раза. +Для таких запросов следует пользоваться методами `query.TxActor.Query`/`query.TxActor.QueryResultSet` на сессии или транзакции, которые отдают итератор по результату без полной материализации. Сессия `query.Session` доступна только из метода `query.Client.Do`, реализующего механизмы выполнения повторных попыток при ошибках. Нужно учитывать, что чтение может быть прервано в любой момент, и в таком случае весь процесс выполнения запроса начнётся заново. То есть функция, переданная в `Do`, может вызываться больше одного раза. + +{% endnote %} + ```go err = db.Query().Do(ctx, From 1b092931237b904d98a7cb1975d87ef8bc31c18c Mon Sep 17 00:00:00 2001 From: Timofey Koolin Date: Thu, 23 Jan 2025 12:15:11 +0300 Subject: [PATCH 21/44] Update ydb/docs/ru/core/dev/example-app/go/index.md Co-authored-by: Ivan Blinkov --- ydb/docs/ru/core/dev/example-app/go/index.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ydb/docs/ru/core/dev/example-app/go/index.md b/ydb/docs/ru/core/dev/example-app/go/index.md index 239d17c644d9..a3381af40e35 100644 --- a/ydb/docs/ru/core/dev/example-app/go/index.md +++ b/ydb/docs/ru/core/dev/example-app/go/index.md @@ -127,9 +127,9 @@ if err != nil { {% include [steps/04_query_processing.md](../_includes/steps/04_query_processing.md) %} -Для выполнения YQL-запросов и чтения результатов используется методы `query.Session.Query`, `query.Session.QueryResultSet` и `query.Session.QueryRow`. +Для выполнения YQL-запросов и чтения результатов используются методы `query.Session.Query`, `query.Session.QueryResultSet` и `query.Session.QueryRow`. -SDK позволяет в явном виде контролировать выполнение транзакций и настраивать необходимый режим выполнения транзакций с помощью структуры `query.TxControl`. +SDK позволяет явно контролировать выполнение транзакций и настраивать необходимый режим выполнения транзакций с помощью структуры `query.TxControl`. ```go readTx := query.TxControl( From a3124abe311d096e7409cba5f598710b8b54fd17 Mon Sep 17 00:00:00 2001 From: Timofey Koolin Date: Tue, 11 Feb 2025 18:37:26 +0000 Subject: [PATCH 22/44] resolve merge conflict --- ydb/docs/ru/core/dev/example-app/go/index.md | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/ydb/docs/ru/core/dev/example-app/go/index.md b/ydb/docs/ru/core/dev/example-app/go/index.md index a3381af40e35..4e7f103cbff5 100644 --- a/ydb/docs/ru/core/dev/example-app/go/index.md +++ b/ydb/docs/ru/core/dev/example-app/go/index.md @@ -71,29 +71,11 @@ db, err := ydb.Open(context.Background(), clusterEndpoint, defer db.Close(ctx) ``` -<<<<<<< HEAD -Объект `db` является входной точкой для работы со всеми сервисами `YDB`: - -* `db.Query()` - клиент query-сервиса; -* `db.Table()` - клиент table-сервиса; -* `db.Discovery()` - клиент discovery-сервиса; -* `db.Topic()` - клиент topic-сервиса; -* `db.Coordination()` - клиент coordination-сервиса; -* `db.Ratelimiter()` - клиент ratelimiter-сервиса; -* `db.Scripting()` - клиент scriptingYQL-сервиса; -* `db.Scheme()` - клиент scheme-сервиса; -* `db.Operation()` - клиент operation-сервиса. - -Выполнение YQL-запросов осуществляется на специальных объектах — сессиях `query.Session`. Сессии хранят контекст выполнения запросов (например, prepared statements и транзакции) и позволяют осуществлять серверную балансировку нагрузки на узлы кластера {{ ydb-short-name }}. - -Клиент предоставляет следующий API для выполнения запросов над таблицами: -======= Объект `db` является входной точкой для работы со всем функционалом {{ ydb-short-name }}, для запросов к таблицам используется Query-сервис: `db.Query()`: Выполнение YQL-запросов осуществляется на специальных объектах — сессиях `query.Session`. Сессии хранят контекст выполнения запросов (например, prepared statements и транзакции) и позволяют осуществлять серверную балансировку нагрузки на узлы кластера {{ ydb-short-name }}. Клиент query-сервиса предоставляет API для выполнения запросов над таблицами: ->>>>>>> d35cd372e84 (style and by comments) * Метод `db.Query().Do(ctx, op)` реализует фоновое создание сессий и повторные попытки выполнить пользовательскую операцию `op func(ctx context.Context, s query.Session) error`, в которую пользовательскому коду передаётся подготовленная сессия `query.Session`. * Метод `db.Query().DoTx(ctx, op)` принимает пользовательскую операцию `op func(ctx context.Context, tx query.TxActor) error`, в которую пользовательскому коду передаётся подготовленная (заранее открытая) транзакция `query.TxActor`. Автоматическое выполнение `Commit` транзакции происходит, если из пользовательской операции возвращается `nil`. В случае возврата ошибки из пользовательской операции для текущей транзакции автоматически вызывается `Rollback`. From 313548bb820e6cbf449b7f9dc2ef9080ae855c86 Mon Sep 17 00:00:00 2001 From: Timofey Koolin Date: Tue, 11 Feb 2025 19:36:21 +0000 Subject: [PATCH 23/44] fix linter --- ydb/docs/ru/core/dev/example-app/go/index.md | 28 ++++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/ydb/docs/ru/core/dev/example-app/go/index.md b/ydb/docs/ru/core/dev/example-app/go/index.md index 71a66e6f456b..754c0f409468 100644 --- a/ydb/docs/ru/core/dev/example-app/go/index.md +++ b/ydb/docs/ru/core/dev/example-app/go/index.md @@ -98,7 +98,7 @@ err = db.Query().Exec(ctx, ` series_info Text, release_date Date, comment Text, - + PRIMARY KEY(series_id) )`, query.WithTxControl(query.NoTx()), ) @@ -163,28 +163,28 @@ if err != nil { ``` - ScanNamed - + ```go var seriesID, title string - var releaseDate time.Time - err = row.ScanNamed(query.Named("series_id", &seriesID), query.Named("title", &title), query.Named("release_date", &releaseDate)) - if err != nil { + var releaseDate time.Time + err = row.ScanNamed(query.Named("series_id", &seriesID), query.Named("title", &title), query.Named("release_date", &releaseDate)) + if err != nil { // обработка ошибки выполнения запроса - } + } ``` -- Scan - +- Scan + ```go var seriesID, title string - var releaseDate time.Time - err = row.Scan(&seriesID, &title, &releaseDate) - if err != nil { + var releaseDate time.Time + err = row.Scan(&seriesID, &title, &releaseDate) + if err != nil { // обработка ошибки выполнения запроса - } + } ``` - -- {% endlist %} + + {% endlist %} {% include [scan_query.md](../_includes/steps/08_scan_query.md) %} From 66f8a56b2c05e8e0f00a9882a0aa8cae59b33a1e Mon Sep 17 00:00:00 2001 From: Timofey Koolin Date: Wed, 12 Feb 2025 11:04:20 +0000 Subject: [PATCH 24/44] small fixes --- ydb/docs/ru/core/dev/example-app/go/index.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ydb/docs/ru/core/dev/example-app/go/index.md b/ydb/docs/ru/core/dev/example-app/go/index.md index 754c0f409468..1e8adc4386ba 100644 --- a/ydb/docs/ru/core/dev/example-app/go/index.md +++ b/ydb/docs/ru/core/dev/example-app/go/index.md @@ -33,7 +33,7 @@ import ( ) ``` -Для взаимодействия с {{ ydb-short-name }} необходимо создать объект подключения к {{ ydb-short-name }}: +Для взаимодействия с {{ ydb-short-name }} необходимо создать экземляр {{ ydb-short-name }}-драйвера: ```go @@ -46,7 +46,7 @@ if err != nil { defer db.Close(context.Backgroung()) ``` -Метод `ydb.Open` возвращает в случае успеха экземпляр драйвера, которые выполняет ряд служебных функций, таких как актуализация сведений о кластере {{ ydb-short-name }} и клиентская балансировка. +Метод `ydb.Open` возвращает в случае успеха экземпляр драйвера, который выполняет ряд служебных функций, таких как актуализация сведений о кластере {{ ydb-short-name }} и клиентская балансировка. Метод `ydb.Open` принимает два обязательных аргумента: From 09a889ae047036f3e975834428265dc53758b4fe Mon Sep 17 00:00:00 2001 From: Timofey Koolin Date: Mon, 17 Feb 2025 12:42:52 +0300 Subject: [PATCH 25/44] Update ydb/docs/ru/core/dev/example-app/go/index.md Co-authored-by: anton-bobkov --- ydb/docs/ru/core/dev/example-app/go/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ydb/docs/ru/core/dev/example-app/go/index.md b/ydb/docs/ru/core/dev/example-app/go/index.md index 1e8adc4386ba..6989d1352c8e 100644 --- a/ydb/docs/ru/core/dev/example-app/go/index.md +++ b/ydb/docs/ru/core/dev/example-app/go/index.md @@ -71,7 +71,7 @@ db, err := ydb.Open(context.Background(), clusterEndpoint, defer db.Close(ctx) ``` -Объект `db` является входной точкой для работы со всем функционалом {{ ydb-short-name }}, для запросов к таблицам используется Query-сервис: `db.Query()`: +Объект `db` является входной точкой для работы с {{ ydb-short-name }}, для запросов к таблицам используется Query-сервис `db.Query()`: Выполнение YQL-запросов осуществляется на специальных объектах — сессиях `query.Session`. Сессии хранят контекст выполнения запросов (например, prepared statements и транзакции) и позволяют осуществлять серверную балансировку нагрузки на узлы кластера {{ ydb-short-name }}. From 7417cd4c55d4fc45223caa2268f22b4f782aee32 Mon Sep 17 00:00:00 2001 From: Timofey Koolin Date: Mon, 24 Feb 2025 15:23:50 +0000 Subject: [PATCH 26/44] init english version --- .../example-app/go/_includes/run_custom.md | 6 +- .../example-app/go/_includes/run_docker.md | 6 +- ydb/docs/en/core/dev/example-app/go/index.md | 349 +++++++++--------- 3 files changed, 174 insertions(+), 187 deletions(-) diff --git a/ydb/docs/en/core/dev/example-app/go/_includes/run_custom.md b/ydb/docs/en/core/dev/example-app/go/_includes/run_custom.md index 4df1cb8e2158..55ad99311f1c 100644 --- a/ydb/docs/en/core/dev/example-app/go/_includes/run_custom.md +++ b/ydb/docs/en/core/dev/example-app/go/_includes/run_custom.md @@ -5,7 +5,7 @@ If authentication is enabled for the database, the [authentication mode](../../. Run the command as follows: ```bash -( export ="" && cd ydb-go-examples && \ +( export ="" && cd ydb-go-sdk/examples && \ go run ./basic -ydb="?database=" ) ``` @@ -19,6 +19,6 @@ where For example: ```bash -( export YDB_ACCESS_TOKEN_CREDENTIALS="t1.9euelZqOnJuJlc..." && cd ydb-go-examples && \ -go run ./basic -ydb="grpcs://ydb.example.com:2135?database=/somepath/somelocation" ) +( export YDB_ACCESS_TOKEN_CREDENTIALS="t1.9euelZqOnJuJlc..." && cd ydb-go-sdk/examples && \ +go run ./basic -ydb="grpcs://ydb.example.com:2135/somepath/somelocation" ) ``` diff --git a/ydb/docs/en/core/dev/example-app/go/_includes/run_docker.md b/ydb/docs/en/core/dev/example-app/go/_includes/run_docker.md index ccb99cf717ba..656808aab9ab 100644 --- a/ydb/docs/en/core/dev/example-app/go/_includes/run_docker.md +++ b/ydb/docs/en/core/dev/example-app/go/_includes/run_docker.md @@ -1,7 +1,7 @@ To connect to a locally deployed {{ ydb-short-name }} database according to the [Docker](../../../../quickstart.md) use case, run the following command in the default configuration: -```bash -( export YDB_ANONYMOUS_CREDENTIALS=1 && cd ydb-go-examples && \ -go run ./basic -ydb="grpc://localhost:2136?database=/local" ) +``` bash +( export YDB_ANONYMOUS_CREDENTIALS=1 && cd ydb-go-sdk/examples && \ +go run ./basic/native/query -ydb="grpc://localhost:2136/local" ) ``` diff --git a/ydb/docs/en/core/dev/example-app/go/index.md b/ydb/docs/en/core/dev/example-app/go/index.md index 2f664569a0e0..b432eb21f80d 100644 --- a/ydb/docs/en/core/dev/example-app/go/index.md +++ b/ydb/docs/en/core/dev/example-app/go/index.md @@ -11,7 +11,7 @@ The following execution scenario is based on [Git](https://git-scm.com/downloads Create a working directory and use it to run the following command from the command line to clone the GitHub repository: ```bash -git clone https://github.com/ydb-platform/ydb-go-examples/ +git clone https://github.com/ydb-platform/ydb-go-sdk.git ``` Next, from the same working directory, run the following command to start the test app: @@ -24,225 +24,212 @@ To work with {{ ydb-short-name }} in `Go`, import the `ydb-go-sdk` driver packag ```go import ( - // general imports from standard library - "context" - "log" - "path" - - // importing the packages ydb-go-sdk - "github.com/ydb-platform/ydb-go-sdk/v3" - "github.com/ydb-platform/ydb-go-sdk/v3/table" // needed to work with table service - "github.com/ydb-platform/ydb-go-sdk/v3/table/options" // needed to work with table service - "github.com/ydb-platform/ydb-go-sdk/v3/table/result" // needed to work with table service - "github.com/ydb-platform/ydb-go-sdk/v3/table/result/named" // needed to work with table service - "github.com/ydb-platform/ydb-go-sdk/v3/table/types" // needed to work with YDB types and values - "github.com/ydb-platform/ydb-go-sdk-auth-environ" // needed to authenticate using environment variables - "github.com/ydb-platform/ydb-go-yc" // to work with YDB in Yandex Cloud + "context" + "log" + "path" + + "github.com/ydb-platform/ydb-go-sdk/v3" + "github.com/ydb-platform/ydb-go-sdk/v3/query" ) ``` -App code snippet for driver initialization: +It is necessary to create {{ ydb-short-name }}-driver for interaction with {{ ydb-short-name }}: ```go -ctx := context.Background() -// connection string -dsn := "grpcs://ydb.serverless.yandexcloud.net:2135/?database=/ru-central1/b1g8skpblkos03malf3s/etn01f8gv9an9sedo9fu" -// IAM token -token := "t1.9euelZrOy8aVmZKJm5HGjceMkMeVj-..." -// create a connection object called db, it is an entry point for YDB services -db, err := ydb.Open(ctx, dsn, -// yc.WithInternalCA(), // use Yandex Cloud certificates - ydb.WithAccessTokenCredentials(token), // authenticate using the token -// ydb.WithAnonimousCredentials(), // authenticate anonymously (for example, using docker ydb) -// yc.WithMetadataCredentials(token), // authenticate from inside a VM in Yandex Cloud or Yandex Function -// yc.WithServiceAccountKeyFileCredentials("~/.ydb/sa.json"), // authenticate in Yandex Cloud using a service account file -// environ.WithEnvironCredentials(ctx), // authenticate using environment variables -) +db, err := ydb.Open(context.Background(), "grpc://localhost:2136/local") if err != nil { - // handle a connection error + // handle connection error } -// driver must be closed when done -defer db.Close(ctx) + +// You should close the driver when exiting from the program +defer db.Close(context.Backgroung()) ``` -The `db` object serves as the entry point for working with {{ ydb-short-name }} services. To interact with the table service, use the `db.Table()` client. This client provides an `API` for making queries to tables. The most commonly used method is `db.Table().Do(ctx, op)`, which handles session creation in the background and retries executing the specified `op` operation, passing the created session to the user's code. +Method `ydb.Open` returns a driver instance if successful. The driver performs several services, such as {{ ydb-short-name }} cluster discovery and client-side load balancing. -The session has a comprehensive `API` that allows you to perform `DDL`, `DML`, `DQL`, and `TCL` requests. +The ydb.Open method takes two required arguments: -{% include [steps/02_create_table.md](../_includes/steps/02_create_table.md) %} +* a context; +* a connection string to {{ ydb-short-name }}. + +There are also many connection options available that let you override the default settings. -To create tables, use the `table.Session.CreateTable()` method: + +By default, anonymous authorization is used. Connecting to the {{ ydb-short-name }} cluster with an authorization token will look like this: ```go -err = db.Table().Do(ctx, - func(ctx context.Context, s table.Session) (err error) { - return s.CreateTable(ctx, path.Join(db.Name(), "series"), - options.WithColumn("series_id", types.TypeUint64), // not null column - options.WithColumn("title", types.Optional(types.TypeUTF8)), - options.WithColumn("series_info", types.Optional(types.TypeUTF8)), - options.WithColumn("release_date", types.Optional(types.TypeDate)), - options.WithColumn("comment", types.Optional(types.TypeUTF8)), - options.WithPrimaryKeyColumn("series_id"), - ) - }, +db, err := ydb.Open(context.Background(), clusterEndpoint, + ydb.WithAccessTokenCredentials(token), ) -if err != nil { - // handling query execution failure -} ``` +You can see the full list of auth providers in the [ydb-go-sdk documentation](https://github.com/ydb-platform/ydb-go-sdk?tab=readme-ov-file#credentials-) and on the [recipes page](../../../recipes/ydb-sdk/auth.md). + +It is necessary to close driver at the end of the work to cleanup resources. + +```go +defer db.Close(ctx) +``` + +Объект `db` является входной точкой для работы со всем функционалом {{ ydb-short-name }}, для запросов к таблицам используется Query-сервис: `db.Query()`: -You can use the `table.Session.DescribeTable()` method to print information about the table structure and make sure that it was properly created: +The `db` struct is the entry point for working with all {{ ydb-short-name }} functionalities. To query to tables, use the query service: `db.Query()`: + +Выполнение YQL-запросов осуществляется на специальных объектах — сессиях `query.Session`. Сессии хранят контекст выполнения запросов (например, prepared statements и транзакции) и позволяют осуществлять серверную балансировку нагрузки на узлы кластера {{ ydb-short-name }}. + +Клиент query-сервиса предоставляет API для выполнения запросов над таблицами: + +* Метод `db.Query().Do(ctx, op)` реализует фоновое создание сессий и повторные попытки выполнить пользовательскую операцию `op func(ctx context.Context, s query.Session) error`, в которую пользовательскому коду передаётся подготовленная сессия `query.Session`. +* Метод `db.Query().DoTx(ctx, op)` принимает пользовательскую операцию `op func(ctx context.Context, tx query.TxActor) error`, в которую пользовательскому коду передаётся подготовленная (заранее открытая) транзакция `query.TxActor`. Автоматическое выполнение `Commit` транзакции происходит, если из пользовательской операции возвращается `nil`. В случае возврата ошибки из пользовательской операции для текущей транзакции автоматически вызывается `Rollback`. +* Метод `db.Query().Exec` является вспомогательным и предназначен для выполнения единичного запроса **без результата** с автоматическими повторными попытками. Метод `Exec` возвращает `nil` в случае успешного выполнения запроса и ошибку, если операция не удалась. +* Метод `db.Query().Query` является вспомогательным и предназначен для выполнения единичного запроса с повторными попытками при необходимости. Текст запроса может содержать несколько выражений с результатами. Метод `Query` возвращает, в случае успеха, материализованный результат запроса (все данные уже прочитаны с сервера и доступны из локальной памяти) `query.Result` и позволяет итерироваться по вложенным спискам строк `query.ResultSet`. Для широких SQL-запросов, возвращающих большое количество строк, материализация результата может привести к проблеме [OOM](https://en.wikipedia.org/wiki/Out_of_memory). +* Метод `db.Query().QueryResultSet` является вспомогательным и предназначен для выполнения единичного запроса с повторными попытками при необходимости. В запросе должно быть ровно одно выражение, возвращающее результат (дополнительно могут присутствовать выражения, не возвращающие результат, например `UPSERT`). Метод `QueryResultSet` возвращает, в случае успеха, материализованный список результатов `query.ResultSet`. Для широких SQL-запросов, возвращающих большое количество строк, материализация результата может привести к проблеме [OOM](https://en.wikipedia.org/wiki/Out_of_memory). +* Метод `db.Query().QueryRow` является вспомогательным и предназначен для выполнения единичного запроса с повторными попытками при необходимости. Метод `QueryRow` возвращает, в случае успеха, единственную строку `query.Row`. + +{% include [steps/02_create_table.md](../_includes/steps/02_create_table.md) %} + +Пример создания таблицы (запрос без возвращаемого результата): ```go -err = db.Table().Do(ctx, - func(ctx context.Context, s table.Session) (err error) { - desc, err := s.DescribeTable(ctx, path.Join(db.Name(), "series")) - if err != nil { - return - } - log.Printf("> describe table: %s\n", tableName) - for _, c := range desc.Columns { - log.Printf(" > column, name: %s, %s\n", c.Type, c.Name) - } - return - }, +import "github.com/ydb-platform/ydb-go-sdk/v3/query" + +err = db.Query().Exec(ctx, ` + CREATE TABLE IF NOT EXISTS series ( + series_id Bytes, + title Text, + series_info Text, + release_date Date, + comment Text, + + PRIMARY KEY(series_id) + )`, query.WithTxControl(query.NoTx()), ) if err != nil { - // handling query execution failure + // обработка ошибки выполнения запроса } ``` {% include [steps/04_query_processing.md](../_includes/steps/04_query_processing.md) %} -To execute YQL queries, use the `table.Session.Execute()` method. -The SDK lets you explicitly control the execution of transactions and configure the transaction execution mode using the `table.TxControl` structure. +Для выполнения YQL-запросов и чтения результатов используются методы `query.Session.Query`, `query.Session.QueryResultSet` и `query.Session.QueryRow`. + +SDK позволяет явно контролировать выполнение транзакций и настраивать необходимый режим выполнения транзакций с помощью структуры `query.TxControl`. ```go -var ( - readTx = table.TxControl( - table.BeginTx( - table.WithOnlineReadOnly(), - ), - table.CommitTx(), - ) +readTx := query.TxControl( + query.BeginTx( + query.WithSnapshotReadOnly(), + ), + query.CommitTx(), ) -err := db.Table().Do(ctx, - func(ctx context.Context, s table.Session) (err error) { - var ( - res result.Result - id uint64 // a variable for required results - title *string // a pointer for optional results - date *time.Time // a pointer for optional results - ) - _, res, err = s.Execute( - ctx, - readTx, - ` - DECLARE $seriesID AS Uint64; - SELECT - series_id, - title, - release_date - FROM - series - WHERE - series_id = $seriesID; - ` -, table.NewQueryParameters( - table.ValueParam("$seriesID", types.Uint64Value(1)), // insert into the query criteria - ), - ) - if err != nil { - return err - } - defer res.Close() // result must be closed - log.Printf("> select_simple_transaction:\n") - for res.NextResultSet(ctx) { - for res.NextRow() { - // use ScanNamed to pass column names from the scan string, - // addresses (and data types) to be assigned the query results - err = res.ScanNamed( - named.Optional("series_id", &id), - named.Optional("title", &title), - named.Optional("release_date", &date), - ) - if err != nil { - return err - } - log.Printf( - " > %d %s %s\n", - id, *title, *date, - ) - } - } - return res.Err() - }, +row, err := db.Query().QueryRow(ctx,` + DECLARE $seriesID AS Uint64; + SELECT + series_id, + title, + release_date + FROM + series + WHERE + series_id = $seriesID;`, + query.WithParameters( + ydb.ParamsBuilder().Param("$seriesID").Uint64(1).Build(), + ), + query.WithTxControl(readTx), ) if err != nil { - // handle a query execution error + // обработка ошибки выполнения запроса } ``` +Для получения данных строки `query.Row` можно использовать следующие методы: + +* `query.Row.ScanStruct` — по названиям колонок, зафиксированным в тегах структуры. +* `query.Row.ScanNamed` — по названиям колонок. +* `query.Row.Scan` — по порядку колонок. + +{% list tabs %} + +- ScanStruct + + ```go + var info struct { + SeriesID string `sql:"series_id"` + Title string `sql:"title"` + ReleaseDate time.Time `sql:"release_date"` + } + err = row.ScanStruct(&info) + if err != nil { + // обработка ошибки выполнения запроса + } + ``` + +- ScanNamed + + ```go + var seriesID, title string + var releaseDate time.Time + err = row.ScanNamed(query.Named("series_id", &seriesID), query.Named("title", &title), query.Named("release_date", &releaseDate)) + if err != nil { + // обработка ошибки выполнения запроса + } + ``` + +- Scan + + ```go + var seriesID, title string + var releaseDate time.Time + err = row.Scan(&seriesID, &title, &releaseDate) + if err != nil { + // обработка ошибки выполнения запроса + } + ``` + + {% endlist %} + {% include [scan_query.md](../_includes/steps/08_scan_query.md) %} -To execute scan queries, use the `table.Session.StreamExecuteScanQuery()` method. +{% note warning %} + +Если ожидаемый объём данных от запроса велик, не следует пытаться загружать их полностью в оперативную память с помощью вспомогательных методов, таких как `query.Client.Query` и `query.Client.QueryResultSet`. Эти методы отдают уже материализованный результат, где весь результат запроса уже прочитан с сервера в локальную память клиентского приложения. При большом количестве возвращаемых строк материализация результата может привести к проблеме [OOM](https://en.wikipedia.org/wiki/Out_of_memory). + +Для таких запросов следует пользоваться методами `query.TxActor.Query`/`query.TxActor.QueryResultSet` на сессии или транзакции, которые отдают итератор по результату без полной материализации. Сессия `query.Session` доступна только из метода `query.Client.Do`, реализующего механизмы выполнения повторных попыток при ошибках. Нужно учитывать, что чтение может быть прервано в любой момент, и в таком случае весь процесс выполнения запроса начнётся заново. То есть функция, переданная в `Do`, может вызываться больше одного раза. + +{% endnote %} + ```go -var ( - query = ` - DECLARE $series AS List; - SELECT series_id, season_id, title, first_aired - FROM seasons - WHERE series_id IN $series - ` - res result.StreamResult -) -err = c.Do(ctx, - func(ctx context.Context, s table.Session) (err error) { - res, err = s.StreamExecuteScanQuery(ctx, query, - table.NewQueryParameters( - table.ValueParam("$series", - types.ListValue( - types.Uint64Value(1), - types.Uint64Value(10), - ), - ), - ), - ) - if err != nil { - return err - } - defer res.Close() // be sure to close the result - var ( - seriesID uint64 - seasonID uint64 - title string - date time.Time - ) - log.Print("\n> scan_query_select:") - for res.NextResultSet(ctx) { - if err = res.Err(); err != nil { - return err - } - for res.NextRow() { - // named.OptionalWithDefault enables you to "deploy" optional - // results or use the default type value in Go - err = res.ScanNamed( - named.Required("series_id", &seriesID), - named.OptionalWithDefault("season_id", &seasonID), - named.OptionalWithDefault("title", &title), - named.OptionalWithDefault("first_aired", &date), - ) - if err != nil { - return err - } - log.Printf("# Season, SeriesId: %d, SeasonId: %d, Title: %s, Air date: %s", seriesID, seasonID, title, date) - } - } - return res.Err() - }, +err = db.Query().Do(ctx, + func(ctx context.Context, s query.Session) error { + rows, err := s.QueryResultSet(ctx,` + SELECT series_id, season_id, title, first_aired + FROM seasons`, + ) + if err != nil { + return err + } + defer rows.Close(ctx) + for row, err := range rows.Rows(ctx) { + if err != nil { + return err + } + var info struct { + SeriesID string `sql:"series_id"` + SeasonID string `sql:"season_id"` + Title string `sql:"title"` + FirstAired time.Time `sql:"first_aired"` + } + err = row.ScanStruct(&info) + if err != nil { + return err + } + fmt.Printf("%+v\n", info) + } + return nil + }, + query.WithIdempotent(), ) if err != nil { - // handling a query execution error + // обработка ошибки выполнения запроса } ``` From fcf27d73c4c1e88a95770fb2c221a454bc888b6f Mon Sep 17 00:00:00 2001 From: Timofey Koolin Date: Fri, 28 Feb 2025 20:40:32 +0000 Subject: [PATCH 27/44] english translation --- ydb/docs/en/core/dev/example-app/go/index.md | 61 ++++++++++---------- ydb/docs/ru/core/dev/example-app/go/index.md | 4 +- 2 files changed, 31 insertions(+), 34 deletions(-) diff --git a/ydb/docs/en/core/dev/example-app/go/index.md b/ydb/docs/en/core/dev/example-app/go/index.md index b432eb21f80d..4f668465b54b 100644 --- a/ydb/docs/en/core/dev/example-app/go/index.md +++ b/ydb/docs/en/core/dev/example-app/go/index.md @@ -6,7 +6,7 @@ This page provides a detailed description of the code for a [test app](https://g ## Downloading and starting {#download} -The following execution scenario is based on [Git](https://git-scm.com/downloads) and [Go](https://go.dev/doc/install). Make sure to install the [YDB Go SDK](../../../reference/ydb-sdk/install.md). +The instructions below assume that [Git](https://git-scm.com/downloads) and [Go](https://go.dev/doc/install) are installed. Make sure to install the [YDB Go SDK](../../../reference/ydb-sdk/install.md). Create a working directory and use it to run the following command from the command line to clone the GitHub repository: @@ -41,8 +41,8 @@ if err != nil { // handle connection error } -// You should close the driver when exiting from the program -defer db.Close(context.Backgroung()) +// You should close the driver when your application finishes its work (for example, when exiting the program). +defer db.Close(context.Background()) ``` Method `ydb.Open` returns a driver instance if successful. The driver performs several services, such as {{ ydb-short-name }} cluster discovery and client-side load balancing. @@ -55,7 +55,7 @@ The ydb.Open method takes two required arguments: There are also many connection options available that let you override the default settings. -By default, anonymous authorization is used. Connecting to the {{ ydb-short-name }} cluster with an authorization token will look like this: +By default, anonymous authorization is used. To connect to the {{ ydb-short-name }} cluster using an authorization token, use the following syntax: ```go db, err := ydb.Open(context.Background(), clusterEndpoint, @@ -64,30 +64,27 @@ db, err := ydb.Open(context.Background(), clusterEndpoint, ``` You can see the full list of auth providers in the [ydb-go-sdk documentation](https://github.com/ydb-platform/ydb-go-sdk?tab=readme-ov-file#credentials-) and on the [recipes page](../../../recipes/ydb-sdk/auth.md). -It is necessary to close driver at the end of the work to cleanup resources. +It is necessary to close the driver at the end of work to clean up resources. ```go defer db.Close(ctx) ``` -Объект `db` является входной точкой для работы со всем функционалом {{ ydb-short-name }}, для запросов к таблицам используется Query-сервис: `db.Query()`: +The `db` struct is the entry point for working with all {{ ydb-short-name }} functionalities. To query tables, use the query service: `db.Query()`: -The `db` struct is the entry point for working with all {{ ydb-short-name }} functionalities. To query to tables, use the query service: `db.Query()`: +YQL queries are executed within special objects called `query.Session`. Sessions store the execution context of queries (for example, transactions) and provide server-side load balancing among the {{ ydb-short-name }} cluster nodes. -Выполнение YQL-запросов осуществляется на специальных объектах — сессиях `query.Session`. Сессии хранят контекст выполнения запросов (например, prepared statements и транзакции) и позволяют осуществлять серверную балансировку нагрузки на узлы кластера {{ ydb-short-name }}. - -Клиент query-сервиса предоставляет API для выполнения запросов над таблицами: - -* Метод `db.Query().Do(ctx, op)` реализует фоновое создание сессий и повторные попытки выполнить пользовательскую операцию `op func(ctx context.Context, s query.Session) error`, в которую пользовательскому коду передаётся подготовленная сессия `query.Session`. -* Метод `db.Query().DoTx(ctx, op)` принимает пользовательскую операцию `op func(ctx context.Context, tx query.TxActor) error`, в которую пользовательскому коду передаётся подготовленная (заранее открытая) транзакция `query.TxActor`. Автоматическое выполнение `Commit` транзакции происходит, если из пользовательской операции возвращается `nil`. В случае возврата ошибки из пользовательской операции для текущей транзакции автоматически вызывается `Rollback`. -* Метод `db.Query().Exec` является вспомогательным и предназначен для выполнения единичного запроса **без результата** с автоматическими повторными попытками. Метод `Exec` возвращает `nil` в случае успешного выполнения запроса и ошибку, если операция не удалась. -* Метод `db.Query().Query` является вспомогательным и предназначен для выполнения единичного запроса с повторными попытками при необходимости. Текст запроса может содержать несколько выражений с результатами. Метод `Query` возвращает, в случае успеха, материализованный результат запроса (все данные уже прочитаны с сервера и доступны из локальной памяти) `query.Result` и позволяет итерироваться по вложенным спискам строк `query.ResultSet`. Для широких SQL-запросов, возвращающих большое количество строк, материализация результата может привести к проблеме [OOM](https://en.wikipedia.org/wiki/Out_of_memory). -* Метод `db.Query().QueryResultSet` является вспомогательным и предназначен для выполнения единичного запроса с повторными попытками при необходимости. В запросе должно быть ровно одно выражение, возвращающее результат (дополнительно могут присутствовать выражения, не возвращающие результат, например `UPSERT`). Метод `QueryResultSet` возвращает, в случае успеха, материализованный список результатов `query.ResultSet`. Для широких SQL-запросов, возвращающих большое количество строк, материализация результата может привести к проблеме [OOM](https://en.wikipedia.org/wiki/Out_of_memory). -* Метод `db.Query().QueryRow` является вспомогательным и предназначен для выполнения единичного запроса с повторными попытками при необходимости. Метод `QueryRow` возвращает, в случае успеха, единственную строку `query.Row`. +The query service client provides an API for executing queries against tables: +* `db.Query().Do(ctx, op)` creates sessions in the background and automatically retries the provided operation `op func(ctx context.Context, s query.Session) error`. As soon as a session is ready, it is passed to the callback. +* `db.Query().DoTx(ctx, op)` automatically handles transaction lifecycle. It provides a prepared transaction object `query.TxActor` to the user-defined function `op func(ctx context.Context, tx query.TxActor)` error. If the operation returns without error (nil), the transaction will commit automatically. If it returns any error, the transaction will rollback automatically. +* `db.Query().Exec` is used to run a single query that returns **no result**, with automatic retry logic on failure. This method returns nil if the execution was successful, or an error otherwise. +* `db.Query().Query` executes a single query containing one or more statements that return a result. It automatically handles retries. Upon successful execution, it returns a fully materialized result (`query.Result`). All result rows are loaded into memory and available for immediate iteration. For queries returning large datasets, this may lead to an [Out of memory](https://en.wikipedia.org/wiki/Out_of_memory) problem. +* `db.Query().QueryResultSet` executes a query containing exactly one statement returning results (it may contain other auxiliary statements without results, e.g. `UPSERT`). Like `db.Query().Query`, it automatically retries failed operations and returns a fully materialized result set (`query.ResultSet`). This can also cause an [OOM](https://en.wikipedia.org/wiki/Out_of_memory) error when receiving large datasets. +* `db.Query().QueryRow` runs queries expected to return exactly one row, with similar automatic retries. On success, it returns a `query.Row` instance. {% include [steps/02_create_table.md](../_includes/steps/02_create_table.md) %} -Пример создания таблицы (запрос без возвращаемого результата): +Example of table creation (a query with no returned result): ```go import "github.com/ydb-platform/ydb-go-sdk/v3/query" @@ -104,15 +101,15 @@ err = db.Query().Exec(ctx, ` )`, query.WithTxControl(query.NoTx()), ) if err != nil { - // обработка ошибки выполнения запроса + // handle query execution error } ``` {% include [steps/04_query_processing.md](../_includes/steps/04_query_processing.md) %} -Для выполнения YQL-запросов и чтения результатов используются методы `query.Session.Query`, `query.Session.QueryResultSet` и `query.Session.QueryRow`. +To execute YQL queries and fetch results, use `query.Session` methods: `query.Session.Query`, `query.Session.QueryResultSet`, or `query.Session.QueryRow`. -SDK позволяет явно контролировать выполнение транзакций и настраивать необходимый режим выполнения транзакций с помощью структуры `query.TxControl`. +The YDB SDK supports explicit transaction control via the `query.TxControl` structure: ```go readTx := query.TxControl( @@ -137,15 +134,15 @@ row, err := db.Query().QueryRow(ctx,` query.WithTxControl(readTx), ) if err != nil { - // обработка ошибки выполнения запроса + // handle query execution error } ``` -Для получения данных строки `query.Row` можно использовать следующие методы: +You can extract row data (`query.Row`) via methods: -* `query.Row.ScanStruct` — по названиям колонок, зафиксированным в тегах структуры. -* `query.Row.ScanNamed` — по названиям колонок. -* `query.Row.Scan` — по порядку колонок. +* `query.Row.ScanStruct` — scans row data into a struct based on struct field tags matching column names. +* `query.Row.ScanNamed` — scans data into variables via explicitly defined column-variable pairs. +* `query.Row.Scan` — scans data directly by column order into provided variables. {% list tabs %} @@ -159,7 +156,7 @@ if err != nil { } err = row.ScanStruct(&info) if err != nil { - // обработка ошибки выполнения запроса + // handle query execution error } ``` @@ -170,7 +167,7 @@ if err != nil { var releaseDate time.Time err = row.ScanNamed(query.Named("series_id", &seriesID), query.Named("title", &title), query.Named("release_date", &releaseDate)) if err != nil { - // обработка ошибки выполнения запроса + // handle query execution error } ``` @@ -181,7 +178,7 @@ if err != nil { var releaseDate time.Time err = row.Scan(&seriesID, &title, &releaseDate) if err != nil { - // обработка ошибки выполнения запроса + // handle query execution error } ``` @@ -191,9 +188,9 @@ if err != nil { {% note warning %} -Если ожидаемый объём данных от запроса велик, не следует пытаться загружать их полностью в оперативную память с помощью вспомогательных методов, таких как `query.Client.Query` и `query.Client.QueryResultSet`. Эти методы отдают уже материализованный результат, где весь результат запроса уже прочитан с сервера в локальную память клиентского приложения. При большом количестве возвращаемых строк материализация результата может привести к проблеме [OOM](https://en.wikipedia.org/wiki/Out_of_memory). +If the expected query result is very large, avoid loading all data into memory using helper methods like `query.Client.Query` or `query.Client.QueryResultSet`. These methods return completely materialized results, storing all rows from the server in local client memory. Large result sets can cause an [OOM](https://en.wikipedia.org/wiki/Out_of_memory) problem. -Для таких запросов следует пользоваться методами `query.TxActor.Query`/`query.TxActor.QueryResultSet` на сессии или транзакции, которые отдают итератор по результату без полной материализации. Сессия `query.Session` доступна только из метода `query.Client.Do`, реализующего механизмы выполнения повторных попыток при ошибках. Нужно учитывать, что чтение может быть прервано в любой момент, и в таком случае весь процесс выполнения запроса начнётся заново. То есть функция, переданная в `Do`, может вызываться больше одного раза. +Instead, use `query.TxActor.Query/query.TxActor.QueryResultSet` methods on a transaction or session. These methods return iterators over results without fully materializing them upfront. The `query.Session` object is accessible via the `query.Client.Do` method, which handles automatic retries. Remember that the reading operation can be interrupted at any time, restarting the whole query process. Therefore, the user function passed to `Do` may run multiple times. {% endnote %} @@ -230,6 +227,6 @@ err = db.Query().Do(ctx, query.WithIdempotent(), ) if err != nil { - // обработка ошибки выполнения запроса + // handle query execution error } ``` diff --git a/ydb/docs/ru/core/dev/example-app/go/index.md b/ydb/docs/ru/core/dev/example-app/go/index.md index 6989d1352c8e..e1df9fcc0c72 100644 --- a/ydb/docs/ru/core/dev/example-app/go/index.md +++ b/ydb/docs/ru/core/dev/example-app/go/index.md @@ -43,7 +43,7 @@ if err != nil { } // При заверщении работы с базой (например выходе из программы) - закройте драйвер -defer db.Close(context.Backgroung()) +defer db.Close(context.Background()) ``` Метод `ydb.Open` возвращает в случае успеха экземпляр драйвера, который выполняет ряд служебных функций, таких как актуализация сведений о кластере {{ ydb-short-name }} и клиентская балансировка. @@ -73,7 +73,7 @@ defer db.Close(ctx) Объект `db` является входной точкой для работы с {{ ydb-short-name }}, для запросов к таблицам используется Query-сервис `db.Query()`: -Выполнение YQL-запросов осуществляется на специальных объектах — сессиях `query.Session`. Сессии хранят контекст выполнения запросов (например, prepared statements и транзакции) и позволяют осуществлять серверную балансировку нагрузки на узлы кластера {{ ydb-short-name }}. +Выполнение YQL-запросов осуществляется на специальных объектах — сессиях `query.Session`. Сессии хранят контекст выполнения запросов (например транзакции) и позволяют осуществлять серверную балансировку нагрузки на узлы кластера {{ ydb-short-name }}. Клиент query-сервиса предоставляет API для выполнения запросов над таблицами: From bdceeeda55c706e8ccc65fc2a8eef79f7c1421b1 Mon Sep 17 00:00:00 2001 From: Timofey Koolin Date: Fri, 28 Feb 2025 20:49:08 +0000 Subject: [PATCH 28/44] linter --- ydb/docs/en/core/dev/example-app/go/index.md | 1 + 1 file changed, 1 insertion(+) diff --git a/ydb/docs/en/core/dev/example-app/go/index.md b/ydb/docs/en/core/dev/example-app/go/index.md index 4f668465b54b..880073ca1e6c 100644 --- a/ydb/docs/en/core/dev/example-app/go/index.md +++ b/ydb/docs/en/core/dev/example-app/go/index.md @@ -75,6 +75,7 @@ The `db` struct is the entry point for working with all {{ ydb-short-name }} fun YQL queries are executed within special objects called `query.Session`. Sessions store the execution context of queries (for example, transactions) and provide server-side load balancing among the {{ ydb-short-name }} cluster nodes. The query service client provides an API for executing queries against tables: + * `db.Query().Do(ctx, op)` creates sessions in the background and automatically retries the provided operation `op func(ctx context.Context, s query.Session) error`. As soon as a session is ready, it is passed to the callback. * `db.Query().DoTx(ctx, op)` automatically handles transaction lifecycle. It provides a prepared transaction object `query.TxActor` to the user-defined function `op func(ctx context.Context, tx query.TxActor)` error. If the operation returns without error (nil), the transaction will commit automatically. If it returns any error, the transaction will rollback automatically. * `db.Query().Exec` is used to run a single query that returns **no result**, with automatic retry logic on failure. This method returns nil if the execution was successful, or an error otherwise. From adc31be95dededc7f2e2773045acc02cce9437c6 Mon Sep 17 00:00:00 2001 From: Timofey Koolin Date: Tue, 4 Mar 2025 14:03:44 +0300 Subject: [PATCH 29/44] Update ydb/docs/en/core/dev/example-app/go/index.md Co-authored-by: anton-bobkov --- ydb/docs/en/core/dev/example-app/go/index.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ydb/docs/en/core/dev/example-app/go/index.md b/ydb/docs/en/core/dev/example-app/go/index.md index 880073ca1e6c..899b44b39a0f 100644 --- a/ydb/docs/en/core/dev/example-app/go/index.md +++ b/ydb/docs/en/core/dev/example-app/go/index.md @@ -49,8 +49,8 @@ Method `ydb.Open` returns a driver instance if successful. The driver performs s The ydb.Open method takes two required arguments: -* a context; -* a connection string to {{ ydb-short-name }}. +* a context +* a {{ ydb-short-name }} connection string There are also many connection options available that let you override the default settings. From 33f33004e06fb6a2679f47b92caba254e22366d6 Mon Sep 17 00:00:00 2001 From: Timofey Koolin Date: Tue, 4 Mar 2025 14:04:14 +0300 Subject: [PATCH 30/44] Update ydb/docs/en/core/dev/example-app/go/index.md Co-authored-by: anton-bobkov --- ydb/docs/en/core/dev/example-app/go/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ydb/docs/en/core/dev/example-app/go/index.md b/ydb/docs/en/core/dev/example-app/go/index.md index 899b44b39a0f..6e49b3b43f5e 100644 --- a/ydb/docs/en/core/dev/example-app/go/index.md +++ b/ydb/docs/en/core/dev/example-app/go/index.md @@ -70,7 +70,7 @@ It is necessary to close the driver at the end of work to clean up resources. defer db.Close(ctx) ``` -The `db` struct is the entry point for working with all {{ ydb-short-name }} functionalities. To query tables, use the query service: `db.Query()`: +The `db` struct is the entry point for working with {{ ydb-short-name }}. To query tables, use the `db.Query()` query service: YQL queries are executed within special objects called `query.Session`. Sessions store the execution context of queries (for example, transactions) and provide server-side load balancing among the {{ ydb-short-name }} cluster nodes. From e5f6d83d7d6c66fe87be7950ef9d568c9f77dcf1 Mon Sep 17 00:00:00 2001 From: Timofey Koolin Date: Tue, 4 Mar 2025 14:04:30 +0300 Subject: [PATCH 31/44] Update ydb/docs/en/core/dev/example-app/go/index.md Co-authored-by: anton-bobkov --- ydb/docs/en/core/dev/example-app/go/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ydb/docs/en/core/dev/example-app/go/index.md b/ydb/docs/en/core/dev/example-app/go/index.md index 6e49b3b43f5e..e6c4aebfb71d 100644 --- a/ydb/docs/en/core/dev/example-app/go/index.md +++ b/ydb/docs/en/core/dev/example-app/go/index.md @@ -74,7 +74,7 @@ The `db` struct is the entry point for working with {{ ydb-short-name }}. To que YQL queries are executed within special objects called `query.Session`. Sessions store the execution context of queries (for example, transactions) and provide server-side load balancing among the {{ ydb-short-name }} cluster nodes. -The query service client provides an API for executing queries against tables: +The query service client provides an API for executing queries: * `db.Query().Do(ctx, op)` creates sessions in the background and automatically retries the provided operation `op func(ctx context.Context, s query.Session) error`. As soon as a session is ready, it is passed to the callback. * `db.Query().DoTx(ctx, op)` automatically handles transaction lifecycle. It provides a prepared transaction object `query.TxActor` to the user-defined function `op func(ctx context.Context, tx query.TxActor)` error. If the operation returns without error (nil), the transaction will commit automatically. If it returns any error, the transaction will rollback automatically. From 4b0f0efad29466f580f0fe8d47dcee6514bfa281 Mon Sep 17 00:00:00 2001 From: Timofey Koolin Date: Tue, 4 Mar 2025 14:04:51 +0300 Subject: [PATCH 32/44] Update ydb/docs/en/core/dev/example-app/go/index.md Co-authored-by: anton-bobkov --- ydb/docs/en/core/dev/example-app/go/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ydb/docs/en/core/dev/example-app/go/index.md b/ydb/docs/en/core/dev/example-app/go/index.md index e6c4aebfb71d..86a51903c79d 100644 --- a/ydb/docs/en/core/dev/example-app/go/index.md +++ b/ydb/docs/en/core/dev/example-app/go/index.md @@ -76,7 +76,7 @@ YQL queries are executed within special objects called `query.Session`. Sessions The query service client provides an API for executing queries: -* `db.Query().Do(ctx, op)` creates sessions in the background and automatically retries the provided operation `op func(ctx context.Context, s query.Session) error`. As soon as a session is ready, it is passed to the callback. +* `db.Query().Do(ctx, op)` creates sessions in the background and automatically retries the provided `op func(ctx context.Context, s query.Session) error` operation if necessary. As soon as a session is ready, it is passed to the callback. * `db.Query().DoTx(ctx, op)` automatically handles transaction lifecycle. It provides a prepared transaction object `query.TxActor` to the user-defined function `op func(ctx context.Context, tx query.TxActor)` error. If the operation returns without error (nil), the transaction will commit automatically. If it returns any error, the transaction will rollback automatically. * `db.Query().Exec` is used to run a single query that returns **no result**, with automatic retry logic on failure. This method returns nil if the execution was successful, or an error otherwise. * `db.Query().Query` executes a single query containing one or more statements that return a result. It automatically handles retries. Upon successful execution, it returns a fully materialized result (`query.Result`). All result rows are loaded into memory and available for immediate iteration. For queries returning large datasets, this may lead to an [Out of memory](https://en.wikipedia.org/wiki/Out_of_memory) problem. From de70dcd5d926f81fe4dba9caac09af8fda4dd8ba Mon Sep 17 00:00:00 2001 From: Timofey Koolin Date: Tue, 4 Mar 2025 14:06:54 +0300 Subject: [PATCH 33/44] Update ydb/docs/en/core/dev/example-app/go/index.md Co-authored-by: anton-bobkov --- ydb/docs/en/core/dev/example-app/go/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ydb/docs/en/core/dev/example-app/go/index.md b/ydb/docs/en/core/dev/example-app/go/index.md index 86a51903c79d..3a6f90c52947 100644 --- a/ydb/docs/en/core/dev/example-app/go/index.md +++ b/ydb/docs/en/core/dev/example-app/go/index.md @@ -81,7 +81,7 @@ The query service client provides an API for executing queries: * `db.Query().Exec` is used to run a single query that returns **no result**, with automatic retry logic on failure. This method returns nil if the execution was successful, or an error otherwise. * `db.Query().Query` executes a single query containing one or more statements that return a result. It automatically handles retries. Upon successful execution, it returns a fully materialized result (`query.Result`). All result rows are loaded into memory and available for immediate iteration. For queries returning large datasets, this may lead to an [Out of memory](https://en.wikipedia.org/wiki/Out_of_memory) problem. * `db.Query().QueryResultSet` executes a query containing exactly one statement returning results (it may contain other auxiliary statements without results, e.g. `UPSERT`). Like `db.Query().Query`, it automatically retries failed operations and returns a fully materialized result set (`query.ResultSet`). This can also cause an [OOM](https://en.wikipedia.org/wiki/Out_of_memory) error when receiving large datasets. -* `db.Query().QueryRow` runs queries expected to return exactly one row, with similar automatic retries. On success, it returns a `query.Row` instance. +* `db.Query().QueryRow` runs queries expected to return exactly one row. It also automatically retries failed operations. On success, it returns a `query.Row` instance. {% include [steps/02_create_table.md](../_includes/steps/02_create_table.md) %} From b79856281b3a22b20181768ba83bd3d5cf0b8ff1 Mon Sep 17 00:00:00 2001 From: Timofey Koolin Date: Tue, 4 Mar 2025 14:07:16 +0300 Subject: [PATCH 34/44] Update ydb/docs/en/core/dev/example-app/go/index.md Co-authored-by: anton-bobkov --- ydb/docs/en/core/dev/example-app/go/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ydb/docs/en/core/dev/example-app/go/index.md b/ydb/docs/en/core/dev/example-app/go/index.md index 3a6f90c52947..4e266a91e5d5 100644 --- a/ydb/docs/en/core/dev/example-app/go/index.md +++ b/ydb/docs/en/core/dev/example-app/go/index.md @@ -45,7 +45,7 @@ if err != nil { defer db.Close(context.Background()) ``` -Method `ydb.Open` returns a driver instance if successful. The driver performs several services, such as {{ ydb-short-name }} cluster discovery and client-side load balancing. +The `ydb.Open` method returns a driver instance if successful. The driver performs several services, such as {{ ydb-short-name }} cluster discovery and client-side load balancing. The ydb.Open method takes two required arguments: From fd316052209ff4f7a1977c2ded069ae7a856d863 Mon Sep 17 00:00:00 2001 From: Timofey Koolin Date: Tue, 4 Mar 2025 14:07:39 +0300 Subject: [PATCH 35/44] Update ydb/docs/en/core/dev/example-app/go/index.md Co-authored-by: anton-bobkov --- ydb/docs/en/core/dev/example-app/go/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ydb/docs/en/core/dev/example-app/go/index.md b/ydb/docs/en/core/dev/example-app/go/index.md index 4e266a91e5d5..e10e83f601df 100644 --- a/ydb/docs/en/core/dev/example-app/go/index.md +++ b/ydb/docs/en/core/dev/example-app/go/index.md @@ -139,7 +139,7 @@ if err != nil { } ``` -You can extract row data (`query.Row`) via methods: +You can extract row data (`query.Row`) using the following methods: * `query.Row.ScanStruct` — scans row data into a struct based on struct field tags matching column names. * `query.Row.ScanNamed` — scans data into variables via explicitly defined column-variable pairs. From ae40f0f80ef538834131e759a5b8a790fd54aa81 Mon Sep 17 00:00:00 2001 From: Timofey Koolin Date: Tue, 4 Mar 2025 14:13:46 +0300 Subject: [PATCH 36/44] Update ydb/docs/en/core/dev/example-app/go/index.md Co-authored-by: anton-bobkov --- ydb/docs/en/core/dev/example-app/go/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ydb/docs/en/core/dev/example-app/go/index.md b/ydb/docs/en/core/dev/example-app/go/index.md index e10e83f601df..7744c3c652d2 100644 --- a/ydb/docs/en/core/dev/example-app/go/index.md +++ b/ydb/docs/en/core/dev/example-app/go/index.md @@ -47,7 +47,7 @@ defer db.Close(context.Background()) The `ydb.Open` method returns a driver instance if successful. The driver performs several services, such as {{ ydb-short-name }} cluster discovery and client-side load balancing. -The ydb.Open method takes two required arguments: +The `ydb.Open` method takes two mandatory arguments: * a context * a {{ ydb-short-name }} connection string From fd1d7912c0fe63b3e6c73fa13e4f000552675828 Mon Sep 17 00:00:00 2001 From: Timofey Koolin Date: Tue, 4 Mar 2025 14:14:05 +0300 Subject: [PATCH 37/44] Update ydb/docs/ru/core/dev/example-app/go/index.md Co-authored-by: anton-bobkov --- ydb/docs/ru/core/dev/example-app/go/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ydb/docs/ru/core/dev/example-app/go/index.md b/ydb/docs/ru/core/dev/example-app/go/index.md index e1df9fcc0c72..e921ac95607d 100644 --- a/ydb/docs/ru/core/dev/example-app/go/index.md +++ b/ydb/docs/ru/core/dev/example-app/go/index.md @@ -55,7 +55,7 @@ defer db.Close(context.Background()) Также доступно множество опций подключения, позволяющих переопределить значения по умолчанию. -По умолчанию используется анонимная авторизация. А подключение к кластеру {{ ydb-short-name }} с использованием токена авторизации будет иметь следующий вид: +По умолчанию используется анонимная аутентификация. А подключение к кластеру {{ ydb-short-name }} с использованием токена будет иметь следующий вид: ```go db, err := ydb.Open(context.Background(), clusterEndpoint, From e7e4049855daee001fee8dcc96b8e750431a1b17 Mon Sep 17 00:00:00 2001 From: Timofey Koolin Date: Tue, 4 Mar 2025 14:14:19 +0300 Subject: [PATCH 38/44] Update ydb/docs/ru/core/dev/example-app/go/index.md Co-authored-by: anton-bobkov --- ydb/docs/ru/core/dev/example-app/go/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ydb/docs/ru/core/dev/example-app/go/index.md b/ydb/docs/ru/core/dev/example-app/go/index.md index e921ac95607d..50e97fe6c353 100644 --- a/ydb/docs/ru/core/dev/example-app/go/index.md +++ b/ydb/docs/ru/core/dev/example-app/go/index.md @@ -63,7 +63,7 @@ db, err := ydb.Open(context.Background(), clusterEndpoint, ) ``` -Полный список провайдеров авторизации приведен в [документации ydb-go-sdk](https://github.com/ydb-platform/ydb-go-sdk?tab=readme-ov-file#credentials-) и в разделе [рецептов](../../../recipes/ydb-sdk/auth.md). +Полный список провайдеров аутентификации приведён в [документации ydb-go-sdk](https://github.com/ydb-platform/ydb-go-sdk?tab=readme-ov-file#credentials-) и в разделе [рецептов](../../../recipes/ydb-sdk/auth.md). В конце работы приложения для очистки ресурсов следует закрыть драйвер: From 1eab427eb73e1030c7986758694d4d97a62d6b2d Mon Sep 17 00:00:00 2001 From: Timofey Koolin Date: Tue, 4 Mar 2025 14:14:32 +0300 Subject: [PATCH 39/44] Update ydb/docs/en/core/dev/example-app/go/index.md Co-authored-by: anton-bobkov --- ydb/docs/en/core/dev/example-app/go/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ydb/docs/en/core/dev/example-app/go/index.md b/ydb/docs/en/core/dev/example-app/go/index.md index 7744c3c652d2..eee33882c8f6 100644 --- a/ydb/docs/en/core/dev/example-app/go/index.md +++ b/ydb/docs/en/core/dev/example-app/go/index.md @@ -55,7 +55,7 @@ The `ydb.Open` method takes two mandatory arguments: There are also many connection options available that let you override the default settings. -By default, anonymous authorization is used. To connect to the {{ ydb-short-name }} cluster using an authorization token, use the following syntax: +By default, anonymous authentication is used. To connect to the {{ ydb-short-name }} cluster using a token, use the following syntax: ```go db, err := ydb.Open(context.Background(), clusterEndpoint, From aa75960d9ee33452274a7e93d310b753794f2da5 Mon Sep 17 00:00:00 2001 From: Timofey Koolin Date: Tue, 4 Mar 2025 14:15:11 +0300 Subject: [PATCH 40/44] Update ydb/docs/en/core/dev/example-app/go/index.md Co-authored-by: anton-bobkov --- ydb/docs/en/core/dev/example-app/go/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ydb/docs/en/core/dev/example-app/go/index.md b/ydb/docs/en/core/dev/example-app/go/index.md index eee33882c8f6..0eca9f79172b 100644 --- a/ydb/docs/en/core/dev/example-app/go/index.md +++ b/ydb/docs/en/core/dev/example-app/go/index.md @@ -80,7 +80,7 @@ The query service client provides an API for executing queries: * `db.Query().DoTx(ctx, op)` automatically handles transaction lifecycle. It provides a prepared transaction object `query.TxActor` to the user-defined function `op func(ctx context.Context, tx query.TxActor)` error. If the operation returns without error (nil), the transaction will commit automatically. If it returns any error, the transaction will rollback automatically. * `db.Query().Exec` is used to run a single query that returns **no result**, with automatic retry logic on failure. This method returns nil if the execution was successful, or an error otherwise. * `db.Query().Query` executes a single query containing one or more statements that return a result. It automatically handles retries. Upon successful execution, it returns a fully materialized result (`query.Result`). All result rows are loaded into memory and available for immediate iteration. For queries returning large datasets, this may lead to an [Out of memory](https://en.wikipedia.org/wiki/Out_of_memory) problem. -* `db.Query().QueryResultSet` executes a query containing exactly one statement returning results (it may contain other auxiliary statements without results, e.g. `UPSERT`). Like `db.Query().Query`, it automatically retries failed operations and returns a fully materialized result set (`query.ResultSet`). This can also cause an [OOM](https://en.wikipedia.org/wiki/Out_of_memory) error when receiving large datasets. +* `db.Query().QueryResultSet` executes a query that contains exactly one statement returning results (it may contain other auxiliary statements that return no results, e.g. `UPSERT`). Like `db.Query().Query`, it automatically retries failed operations and returns a fully materialized result set (`query.ResultSet`). Queries that return large datasets may cause an [OOM](https://en.wikipedia.org/wiki/Out_of_memory) error. * `db.Query().QueryRow` runs queries expected to return exactly one row. It also automatically retries failed operations. On success, it returns a `query.Row` instance. {% include [steps/02_create_table.md](../_includes/steps/02_create_table.md) %} From af338a12b9a2888f3eb312b4581bdc9dfe4f2724 Mon Sep 17 00:00:00 2001 From: Timofey Koolin Date: Tue, 4 Mar 2025 14:15:31 +0300 Subject: [PATCH 41/44] Update ydb/docs/en/core/dev/example-app/go/index.md Co-authored-by: anton-bobkov --- ydb/docs/en/core/dev/example-app/go/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ydb/docs/en/core/dev/example-app/go/index.md b/ydb/docs/en/core/dev/example-app/go/index.md index 0eca9f79172b..f1d2e174ea5c 100644 --- a/ydb/docs/en/core/dev/example-app/go/index.md +++ b/ydb/docs/en/core/dev/example-app/go/index.md @@ -33,7 +33,7 @@ import ( ) ``` -It is necessary to create {{ ydb-short-name }}-driver for interaction with {{ ydb-short-name }}: +To interact with {{ ydb-short-name }}, it is necessary to create a {{ ydb-short-name }} driver: ```go db, err := ydb.Open(context.Background(), "grpc://localhost:2136/local") From 62b8d8af13f7c163d2bc59aab1fc1915b23ca1cf Mon Sep 17 00:00:00 2001 From: Timofey Koolin Date: Tue, 4 Mar 2025 11:18:14 +0000 Subject: [PATCH 42/44] fix-typo --- ydb/docs/en/core/dev/example-app/go/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ydb/docs/en/core/dev/example-app/go/index.md b/ydb/docs/en/core/dev/example-app/go/index.md index f1d2e174ea5c..46e8c04b65cf 100644 --- a/ydb/docs/en/core/dev/example-app/go/index.md +++ b/ydb/docs/en/core/dev/example-app/go/index.md @@ -77,7 +77,7 @@ YQL queries are executed within special objects called `query.Session`. Sessions The query service client provides an API for executing queries: * `db.Query().Do(ctx, op)` creates sessions in the background and automatically retries the provided `op func(ctx context.Context, s query.Session) error` operation if necessary. As soon as a session is ready, it is passed to the callback. -* `db.Query().DoTx(ctx, op)` automatically handles transaction lifecycle. It provides a prepared transaction object `query.TxActor` to the user-defined function `op func(ctx context.Context, tx query.TxActor)` error. If the operation returns without error (nil), the transaction will commit automatically. If it returns any error, the transaction will rollback automatically. +* `db.Query().DoTx(ctx, op)` automatically handles transaction lifecycle. It provides a prepared transaction object `query.TxActor` to the user-defined function `op func(ctx context.Context, tx query.TxActor) error`. If the operation returns without error (nil), the transaction will commit automatically. If it returns any error, the transaction will rollback automatically. * `db.Query().Exec` is used to run a single query that returns **no result**, with automatic retry logic on failure. This method returns nil if the execution was successful, or an error otherwise. * `db.Query().Query` executes a single query containing one or more statements that return a result. It automatically handles retries. Upon successful execution, it returns a fully materialized result (`query.Result`). All result rows are loaded into memory and available for immediate iteration. For queries returning large datasets, this may lead to an [Out of memory](https://en.wikipedia.org/wiki/Out_of_memory) problem. * `db.Query().QueryResultSet` executes a query that contains exactly one statement returning results (it may contain other auxiliary statements that return no results, e.g. `UPSERT`). Like `db.Query().Query`, it automatically retries failed operations and returns a fully materialized result set (`query.ResultSet`). Queries that return large datasets may cause an [OOM](https://en.wikipedia.org/wiki/Out_of_memory) error. From 4acc6c6f3b7692949cf2210126fa0e6d2938366b Mon Sep 17 00:00:00 2001 From: Timofey Koolin Date: Tue, 4 Mar 2025 13:11:32 +0000 Subject: [PATCH 43/44] fix style --- ydb/docs/en/core/dev/example-app/go/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ydb/docs/en/core/dev/example-app/go/index.md b/ydb/docs/en/core/dev/example-app/go/index.md index 46e8c04b65cf..21c0abfb6748 100644 --- a/ydb/docs/en/core/dev/example-app/go/index.md +++ b/ydb/docs/en/core/dev/example-app/go/index.md @@ -77,7 +77,7 @@ YQL queries are executed within special objects called `query.Session`. Sessions The query service client provides an API for executing queries: * `db.Query().Do(ctx, op)` creates sessions in the background and automatically retries the provided `op func(ctx context.Context, s query.Session) error` operation if necessary. As soon as a session is ready, it is passed to the callback. -* `db.Query().DoTx(ctx, op)` automatically handles transaction lifecycle. It provides a prepared transaction object `query.TxActor` to the user-defined function `op func(ctx context.Context, tx query.TxActor) error`. If the operation returns without error (nil), the transaction will commit automatically. If it returns any error, the transaction will rollback automatically. +* `db.Query().DoTx(ctx, op)` automatically handles transaction lifecycle. It provides a prepared transaction object `query.TxActor` to the user-defined function `op func(ctx context.Context, tx query.TxActor)` error. If the operation returns without error (nil), the transaction will commit automatically. If the operation returns any error, the transaction will rollback automatically. * `db.Query().Exec` is used to run a single query that returns **no result**, with automatic retry logic on failure. This method returns nil if the execution was successful, or an error otherwise. * `db.Query().Query` executes a single query containing one or more statements that return a result. It automatically handles retries. Upon successful execution, it returns a fully materialized result (`query.Result`). All result rows are loaded into memory and available for immediate iteration. For queries returning large datasets, this may lead to an [Out of memory](https://en.wikipedia.org/wiki/Out_of_memory) problem. * `db.Query().QueryResultSet` executes a query that contains exactly one statement returning results (it may contain other auxiliary statements that return no results, e.g. `UPSERT`). Like `db.Query().Query`, it automatically retries failed operations and returns a fully materialized result set (`query.ResultSet`). Queries that return large datasets may cause an [OOM](https://en.wikipedia.org/wiki/Out_of_memory) error. From 7ee55d4a5d369447d92e41755d817a748a84bc73 Mon Sep 17 00:00:00 2001 From: Timofey Koolin Date: Fri, 7 Mar 2025 12:13:42 +0300 Subject: [PATCH 44/44] Apply suggestions from code review Co-authored-by: Ivan Blinkov --- ydb/docs/en/core/dev/example-app/go/index.md | 22 ++++++++++---------- ydb/docs/ru/core/dev/example-app/go/index.md | 18 ++++++++-------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/ydb/docs/en/core/dev/example-app/go/index.md b/ydb/docs/en/core/dev/example-app/go/index.md index 21c0abfb6748..1727ebac0623 100644 --- a/ydb/docs/en/core/dev/example-app/go/index.md +++ b/ydb/docs/en/core/dev/example-app/go/index.md @@ -77,15 +77,15 @@ YQL queries are executed within special objects called `query.Session`. Sessions The query service client provides an API for executing queries: * `db.Query().Do(ctx, op)` creates sessions in the background and automatically retries the provided `op func(ctx context.Context, s query.Session) error` operation if necessary. As soon as a session is ready, it is passed to the callback. -* `db.Query().DoTx(ctx, op)` automatically handles transaction lifecycle. It provides a prepared transaction object `query.TxActor` to the user-defined function `op func(ctx context.Context, tx query.TxActor)` error. If the operation returns without error (nil), the transaction will commit automatically. If the operation returns any error, the transaction will rollback automatically. -* `db.Query().Exec` is used to run a single query that returns **no result**, with automatic retry logic on failure. This method returns nil if the execution was successful, or an error otherwise. -* `db.Query().Query` executes a single query containing one or more statements that return a result. It automatically handles retries. Upon successful execution, it returns a fully materialized result (`query.Result`). All result rows are loaded into memory and available for immediate iteration. For queries returning large datasets, this may lead to an [Out of memory](https://en.wikipedia.org/wiki/Out_of_memory) problem. -* `db.Query().QueryResultSet` executes a query that contains exactly one statement returning results (it may contain other auxiliary statements that return no results, e.g. `UPSERT`). Like `db.Query().Query`, it automatically retries failed operations and returns a fully materialized result set (`query.ResultSet`). Queries that return large datasets may cause an [OOM](https://en.wikipedia.org/wiki/Out_of_memory) error. +* `db.Query().DoTx(ctx, op)` automatically handles the transaction lifecycle. It provides a prepared transaction object, `query.TxActor`, to the user-defined function `op func(ctx context.Context, tx query.TxActor)` error. If the operation returns without an error (nil), the transaction commits automatically. If the operation returns an error, the transaction rolls back automatically. +* `db.Query().Exec` runs a single query that returns **no result**, with automatic retry logic on failure. This method returns nil if the execution is successful or an error otherwise. +* `db.Query().Query` executes a single query containing one or more statements that return a result. It automatically handles retries. Upon successful execution, it returns a fully materialized result (`query.Result`). All result rows are loaded into memory and available for immediate iteration. For queries returning large datasets, this may lead to an [out of memory](https://en.wikipedia.org/wiki/Out_of_memory) problem. +* `db.Query().QueryResultSet` executes a query that contains exactly one statement returning results (it may contain other auxiliary statements that return no results, such as `UPSERT`). Like `db.Query().Query`, it automatically retries failed operations and returns a fully materialized result set (`query.ResultSet`). Queries that return large datasets may cause an [OOM](https://en.wikipedia.org/wiki/Out_of_memory) error. * `db.Query().QueryRow` runs queries expected to return exactly one row. It also automatically retries failed operations. On success, it returns a `query.Row` instance. {% include [steps/02_create_table.md](../_includes/steps/02_create_table.md) %} -Example of table creation (a query with no returned result): +Example of a query with no returned result (table creation): ```go import "github.com/ydb-platform/ydb-go-sdk/v3/query" @@ -110,7 +110,7 @@ if err != nil { To execute YQL queries and fetch results, use `query.Session` methods: `query.Session.Query`, `query.Session.QueryResultSet`, or `query.Session.QueryRow`. -The YDB SDK supports explicit transaction control via the `query.TxControl` structure: +The {{ ydb-short-name }} SDK supports explicit transaction control via the `query.TxControl` structure: ```go readTx := query.TxControl( @@ -141,9 +141,9 @@ if err != nil { You can extract row data (`query.Row`) using the following methods: -* `query.Row.ScanStruct` — scans row data into a struct based on struct field tags matching column names. -* `query.Row.ScanNamed` — scans data into variables via explicitly defined column-variable pairs. -* `query.Row.Scan` — scans data directly by column order into provided variables. +* `query.Row.ScanStruct` — scans row data into a struct based on struct field tags that match column names. +* `query.Row.ScanNamed` — scans data into variables using explicitly defined column-variable pairs. +* `query.Row.Scan` — scans data directly by column order into the provided variables. {% list tabs %} @@ -189,9 +189,9 @@ You can extract row data (`query.Row`) using the following methods: {% note warning %} -If the expected query result is very large, avoid loading all data into memory using helper methods like `query.Client.Query` or `query.Client.QueryResultSet`. These methods return completely materialized results, storing all rows from the server in local client memory. Large result sets can cause an [OOM](https://en.wikipedia.org/wiki/Out_of_memory) problem. +If the expected query result is very large, avoid loading all data into memory using helper methods like `query.Client.Query` or `query.Client.QueryResultSet`. These methods return fully materialized results, storing all rows from the server in local client memory. Large result sets can cause an [OOM](https://en.wikipedia.org/wiki/Out_of_memory) problem. -Instead, use `query.TxActor.Query/query.TxActor.QueryResultSet` methods on a transaction or session. These methods return iterators over results without fully materializing them upfront. The `query.Session` object is accessible via the `query.Client.Do` method, which handles automatic retries. Remember that the reading operation can be interrupted at any time, restarting the whole query process. Therefore, the user function passed to `Do` may run multiple times. +Instead, use the `query.TxActor.Query` or `query.TxActor.QueryResultSet` methods on a transaction or session. These methods return iterators over results without fully materializing them upfront. The `query.Session` object is accessible via the `query.Client.Do` method, which handles automatic retries. Keep in mind that the read operation can be interrupted at any time, restarting the entire query process. Therefore, the user function passed to `Do` may run multiple times. {% endnote %} diff --git a/ydb/docs/ru/core/dev/example-app/go/index.md b/ydb/docs/ru/core/dev/example-app/go/index.md index 50e97fe6c353..fc0b17ca4ac0 100644 --- a/ydb/docs/ru/core/dev/example-app/go/index.md +++ b/ydb/docs/ru/core/dev/example-app/go/index.md @@ -42,7 +42,7 @@ if err != nil { // обработка ошибки подключения } -// При заверщении работы с базой (например выходе из программы) - закройте драйвер +// При заверщении работы с базой (например, выходе из программы) закройте драйвер defer db.Close(context.Background()) ``` @@ -71,22 +71,22 @@ db, err := ydb.Open(context.Background(), clusterEndpoint, defer db.Close(ctx) ``` -Объект `db` является входной точкой для работы с {{ ydb-short-name }}, для запросов к таблицам используется Query-сервис `db.Query()`: +Объект `db` является входной точкой для работы с {{ ydb-short-name }}, а для запросов к таблицам используется Query-сервис `db.Query()`. -Выполнение YQL-запросов осуществляется на специальных объектах — сессиях `query.Session`. Сессии хранят контекст выполнения запросов (например транзакции) и позволяют осуществлять серверную балансировку нагрузки на узлы кластера {{ ydb-short-name }}. +Выполнение YQL-запросов осуществляется на специальных объектах — сессиях `query.Session`. Сессии хранят контекст выполнения запросов (например, транзакции) и позволяют осуществлять серверную балансировку нагрузки на узлы кластера {{ ydb-short-name }}. -Клиент query-сервиса предоставляет API для выполнения запросов над таблицами: +Клиент Query-сервиса предоставляет API для выполнения запросов к таблицам: * Метод `db.Query().Do(ctx, op)` реализует фоновое создание сессий и повторные попытки выполнить пользовательскую операцию `op func(ctx context.Context, s query.Session) error`, в которую пользовательскому коду передаётся подготовленная сессия `query.Session`. -* Метод `db.Query().DoTx(ctx, op)` принимает пользовательскую операцию `op func(ctx context.Context, tx query.TxActor) error`, в которую пользовательскому коду передаётся подготовленная (заранее открытая) транзакция `query.TxActor`. Автоматическое выполнение `Commit` транзакции происходит, если из пользовательской операции возвращается `nil`. В случае возврата ошибки из пользовательской операции для текущей транзакции автоматически вызывается `Rollback`. +* Метод `db.Query().DoTx(ctx, op)` принимает пользовательскую операцию `op func(ctx context.Context, tx query.TxActor) error`, в которую пользовательскому коду передаётся подготовленная (заранее открытая) транзакция `query.TxActor`. Автоматическое выполнение `Commit` транзакции происходит, если из пользовательской операции возвращается `nil`. В случае возврата ошибки для текущей транзакции автоматически вызывается `Rollback`. * Метод `db.Query().Exec` является вспомогательным и предназначен для выполнения единичного запроса **без результата** с автоматическими повторными попытками. Метод `Exec` возвращает `nil` в случае успешного выполнения запроса и ошибку, если операция не удалась. -* Метод `db.Query().Query` является вспомогательным и предназначен для выполнения единичного запроса с повторными попытками при необходимости. Текст запроса может содержать несколько выражений с результатами. Метод `Query` возвращает, в случае успеха, материализованный результат запроса (все данные уже прочитаны с сервера и доступны из локальной памяти) `query.Result` и позволяет итерироваться по вложенным спискам строк `query.ResultSet`. Для широких SQL-запросов, возвращающих большое количество строк, материализация результата может привести к проблеме [OOM](https://en.wikipedia.org/wiki/Out_of_memory). +* Метод `db.Query().Query` является вспомогательным и предназначен для выполнения единичного запроса с повторными попытками при необходимости. Текст запроса может содержать несколько выражений с результатами. Метод `Query` возвращает, в случае успеха, материализованный результат запроса (все данные уже прочитаны с сервера и доступны в локальной памяти) `query.Result` и позволяет итерироваться по вложенным спискам строк `query.ResultSet`. Для широких SQL-запросов, возвращающих большое количество строк, материализация результата может привести к проблеме [OOM](https://en.wikipedia.org/wiki/Out_of_memory). * Метод `db.Query().QueryResultSet` является вспомогательным и предназначен для выполнения единичного запроса с повторными попытками при необходимости. В запросе должно быть ровно одно выражение, возвращающее результат (дополнительно могут присутствовать выражения, не возвращающие результат, например `UPSERT`). Метод `QueryResultSet` возвращает, в случае успеха, материализованный список результатов `query.ResultSet`. Для широких SQL-запросов, возвращающих большое количество строк, материализация результата может привести к проблеме [OOM](https://en.wikipedia.org/wiki/Out_of_memory). * Метод `db.Query().QueryRow` является вспомогательным и предназначен для выполнения единичного запроса с повторными попытками при необходимости. Метод `QueryRow` возвращает, в случае успеха, единственную строку `query.Row`. {% include [steps/02_create_table.md](../_includes/steps/02_create_table.md) %} -Пример создания таблицы (запрос без возвращаемого результата): +Пример запроса без возвращаемого результата (создание таблицы): ```go import "github.com/ydb-platform/ydb-go-sdk/v3/query" @@ -190,9 +190,9 @@ if err != nil { {% note warning %} -Если ожидаемый объём данных от запроса велик, не следует пытаться загружать их полностью в оперативную память с помощью вспомогательных методов, таких как `query.Client.Query` и `query.Client.QueryResultSet`. Эти методы отдают уже материализованный результат, где весь результат запроса уже прочитан с сервера в локальную память клиентского приложения. При большом количестве возвращаемых строк материализация результата может привести к проблеме [OOM](https://en.wikipedia.org/wiki/Out_of_memory). +Если ожидаемый объём данных от запроса велик, не следует пытаться загружать их полностью в оперативную память с помощью вспомогательных методов, таких как `query.Client.Query` и `query.Client.QueryResultSet`. Эти методы возвращают уже материализованный результат, при котором все данные запроса загружены с сервера в локальную память клиентского приложения. При большом количестве возвращаемых строк материализация результата может привести к проблеме [OOM](https://en.wikipedia.org/wiki/Out_of_memory). -Для таких запросов следует пользоваться методами `query.TxActor.Query`/`query.TxActor.QueryResultSet` на сессии или транзакции, которые отдают итератор по результату без полной материализации. Сессия `query.Session` доступна только из метода `query.Client.Do`, реализующего механизмы выполнения повторных попыток при ошибках. Нужно учитывать, что чтение может быть прервано в любой момент, и в таком случае весь процесс выполнения запроса начнётся заново. То есть функция, переданная в `Do`, может вызываться больше одного раза. +Для таких запросов следует использовать методы `query.TxActor.Query` или `query.TxActor.QueryResultSet` на сессии или транзакции, которые предоставляют итератор по результату без полной материализации. Сессия `query.Session` доступна только из метода `query.Client.Do`, реализующего механизмы повторных попыток при ошибках. Нужно учитывать, что чтение может быть прервано в любой момент, и в таком случае весь процесс выполнения запроса начнётся заново. То есть функция, переданная в `Do`, может вызываться более одного раза. {% endnote %}