|
| 1 | +--- |
| 2 | +id: ydb |
| 3 | +title: YDB |
| 4 | +--- |
| 5 | + |
| 6 | +## Overview |
| 7 | + |
| 8 | +[YDB](https://ydb.tech/) is a distributed SQL database developed by Yandex. It provides horizontal scalability, |
| 9 | +strong consistency, and automatic handling of transient errors. This page covers YDB-specific features and |
| 10 | +considerations when using ent with YDB. |
| 11 | + |
| 12 | +:::note |
| 13 | +YDB support is currently in **preview** and requires the [Atlas migration engine](migrate.md#atlas-integration). |
| 14 | +::: |
| 15 | + |
| 16 | +## Opening a Connection |
| 17 | + |
| 18 | +To connect to YDB, use the `ydb.Open()` function from the `entgo.io/ent/dialect/ydb` package: |
| 19 | + |
| 20 | +```go |
| 21 | +package main |
| 22 | + |
| 23 | +import ( |
| 24 | + "context" |
| 25 | + "log" |
| 26 | + |
| 27 | + "entdemo/ent" |
| 28 | + |
| 29 | + "entgo.io/ent/dialect/ydb" |
| 30 | +) |
| 31 | + |
| 32 | +func main() { |
| 33 | + // Open connection to YDB |
| 34 | + client, err := ent.Open("ydb", "grpc://localhost:2136/local") |
| 35 | + if err != nil { |
| 36 | + log.Fatalf("failed opening connection to ydb: %v", err) |
| 37 | + } |
| 38 | + defer client.Close() |
| 39 | + |
| 40 | + ctx := context.Background() |
| 41 | + // Run the auto migration tool |
| 42 | + if err := client.Schema.Create(ctx); err != nil { |
| 43 | + log.Fatalf("failed creating schema resources: %v", err) |
| 44 | + } |
| 45 | +} |
| 46 | +``` |
| 47 | + |
| 48 | +## Automatic Retry Mechanism |
| 49 | + |
| 50 | +YDB requires special handling for transient errors (network issues, temporary unavailability, etc.). |
| 51 | +The ent YDB driver integrates with [ydb-go-sdk's retry package](https://pkg.go.dev/github.com/ydb-platform/ydb-go-sdk/v3/retry) |
| 52 | +to automatically handle these scenarios. |
| 53 | + |
| 54 | +### Using WithRetryOptions |
| 55 | + |
| 56 | +All CRUD operations support the `WithRetryOptions()` method to configure retry behavior: |
| 57 | + |
| 58 | +```go |
| 59 | +import "github.com/ydb-platform/ydb-go-sdk/v3/retry" |
| 60 | + |
| 61 | +// Create with retry options |
| 62 | +user, err := client.User.Create(). |
| 63 | + SetName("John"). |
| 64 | + SetAge(30). |
| 65 | + WithRetryOptions(retry.WithIdempotent(true)). |
| 66 | + Save(ctx) |
| 67 | + |
| 68 | +// Query with retry options |
| 69 | +users, err := client.User.Query(). |
| 70 | + Where(user.AgeGT(18)). |
| 71 | + WithRetryOptions(retry.WithIdempotent(true)). |
| 72 | + All(ctx) |
| 73 | + |
| 74 | +// Update with retry options |
| 75 | +affected, err := client.User.Update(). |
| 76 | + Where(user.NameEQ("John")). |
| 77 | + SetAge(31). |
| 78 | + WithRetryOptions(retry.WithIdempotent(true)). |
| 79 | + Save(ctx) |
| 80 | + |
| 81 | +// Delete with retry options |
| 82 | +affected, err := client.User.Delete(). |
| 83 | + Where(user.NameEQ("John")). |
| 84 | + WithRetryOptions(retry.WithIdempotent(true)). |
| 85 | + Exec(ctx) |
| 86 | +``` |
| 87 | + |
| 88 | +### Retry Options |
| 89 | + |
| 90 | +Common retry options from `ydb-go-sdk`: |
| 91 | + |
| 92 | +| Option | Description | |
| 93 | +|--------|-------------| |
| 94 | +| `retry.WithIdempotent(true)` | Mark operation as idempotent, allowing retries on more error types | |
| 95 | +| `retry.WithLabel(string)` | Add a label for debugging/tracing | |
| 96 | +| `retry.WithTrace(trace.Retry)` | Enable retry tracing | |
| 97 | + |
| 98 | +## YDB-Specific SQL Features |
| 99 | + |
| 100 | +The ent SQL builder supports several YDB-specific SQL constructs that are used internally |
| 101 | +or can be leveraged for advanced use cases. |
| 102 | + |
| 103 | +### UPSERT and REPLACE |
| 104 | + |
| 105 | +YDB doesn't support the standard `ON CONFLICT` clause. Instead, it uses `UPSERT` and `REPLACE` statements: |
| 106 | + |
| 107 | +- **UPSERT**: Inserts a new row or updates an existing row if a conflict occurs |
| 108 | +- **REPLACE**: Replaces the entire row if a conflict occurs |
| 109 | + |
| 110 | +Ent automatically uses `UPSERT` when you configure `OnConflict` options in your create operations. |
| 111 | + |
| 112 | +### BATCH Operations |
| 113 | + |
| 114 | +For large tables, YDB provides `BATCH UPDATE` and `BATCH DELETE` statements that process data |
| 115 | +in batches, minimizing lock invalidation risk. These are used internally by ent when appropriate. |
| 116 | + |
| 117 | +### Special JOIN Types |
| 118 | + |
| 119 | +YDB supports additional JOIN types beyond the standard SQL joins: |
| 120 | + |
| 121 | +| Join Type | Description | |
| 122 | +|-----------|-------------| |
| 123 | +| `LEFT SEMI JOIN` | Returns rows from left table that have matches in right table | |
| 124 | +| `RIGHT SEMI JOIN` | Returns rows from right table that have matches in left table | |
| 125 | +| `LEFT ONLY JOIN` | Returns rows from left table that have no matches in right table | |
| 126 | +| `RIGHT ONLY JOIN` | Returns rows from right table that have no matches in left table | |
| 127 | +| `EXCLUSION JOIN` | Returns rows that don't have matches in either table | |
| 128 | + |
| 129 | +### VIEW Clause for Secondary Indexes |
| 130 | + |
| 131 | +YDB allows explicit use of secondary indexes via the `VIEW` clause. This is an optimization |
| 132 | +hint that tells YDB to use a specific index for the query. |
| 133 | + |
| 134 | +### Named Parameters |
| 135 | + |
| 136 | +YDB uses named parameters with the `$paramName` syntax (e.g., `$p1`, `$p2`) instead of |
| 137 | +positional placeholders. Ent handles this automatically. |
| 138 | + |
| 139 | +## Known Limitations |
| 140 | + |
| 141 | +When using ent with YDB, be aware of the following limitations: |
| 142 | + |
| 143 | +### No Correlated Subqueries |
| 144 | + |
| 145 | +YDB doesn't support correlated subqueries with `EXISTS` or `NOT EXISTS`. Ent automatically |
| 146 | +rewrites such queries to use `IN` with subqueries instead. |
| 147 | + |
| 148 | +### No Nested Transactions |
| 149 | + |
| 150 | +YDB uses flat transactions and doesn't support nested transactions. The ent YDB driver |
| 151 | +handles this by returning a no-op transaction when nested transactions are requested. |
| 152 | + |
| 153 | +### Float/Double Index Restriction |
| 154 | + |
| 155 | +YDB doesn't allow `Float` or `Double` types as index keys. If you define an index on a |
| 156 | +float field, it will be skipped during migration. |
| 157 | + |
| 158 | +### No Native Enum Types |
| 159 | + |
| 160 | +YDB doesn't support enum types in DDL statements. Ent maps enum fields to `Utf8` (string) |
| 161 | +type, with validation handled at the application level. |
| 162 | + |
| 163 | +### RowsAffected Behavior |
| 164 | + |
| 165 | +YDB's `RowsAffected()` doesn't return accurate counts. The ent driver uses the `RETURNING` |
| 166 | +clause internally to count affected rows when needed. |
| 167 | + |
| 168 | +### Primary Key Requirements |
| 169 | + |
| 170 | +YDB requires explicit primary keys for all tables. Make sure your ent schemas define |
| 171 | +appropriate ID fields. |
| 172 | + |
| 173 | +## Example Project |
| 174 | + |
| 175 | +A complete working example is available in the ent repository: |
| 176 | +[examples/ydb](https://github.com/ent/ent/tree/master/examples/ydb) |
| 177 | + |
| 178 | +This example demonstrates: |
| 179 | +- Opening a YDB connection |
| 180 | +- Schema creation with migrations |
| 181 | +- CRUD operations with retry options |
| 182 | +- Edge traversals |
0 commit comments