You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Add a new pattern for "prepared inserts". It works like this:
* Call `BeginInsert` with an `INSERT` query with optional columns
and ending in `VALUES`. No values should be included in the string.
* It returns a `Block` pre-configured with columns as
declared in the `INSERT` statement
* Add data to the block and periodically call `InsertData` to insert
data and clear the block.
* Call `EndInsert()` or just let the `Client` object go out of scope
to signal the server that it's done inserting.
This allows one to send smaller batches of blocks, thereby using less
memory, but still in a single ClickHouse `INSERT` operation.
Expected to be useful in the Postgres foreign data wrapper insert API,
where multiple rows can be inserted at once but its API handles
one-at-a-time insertion. It will also support the FDW COPY API, which
can submit huge batches of data to insert, as well.
- run `rm -rf build && cmake -B build -S . && cmake --build build -j32` to remove remainders of the previous builds, run CMake and build the
158
158
application. The generated binary is located in location `build/application-example`.
159
159
160
+
## Batch Insertion
161
+
162
+
In addition to the `Insert` method, which inserts all the data in a block in a
163
+
single call, you can use the `BeginInsert` / `InsertData` / `EndInsert`
164
+
pattern to insert batches of data. This can be useful for managing larger data
165
+
sets without inflating memory with the entire set.
166
+
167
+
To use it pass `BeginInsert` an `INSERT` statement ending in `VALUES` but with
168
+
no actual values. Use the resulting `Block` to append batches of data, sending
169
+
each to the sever with `InsertData`. Finally, call `EndInsert` (or let the
170
+
client go out of scope) to signal the server that insertion is complete.
171
+
Example:
172
+
173
+
```cpp
174
+
// Start the insertion.
175
+
auto block = client->BeginInsert("INSERT INTO foo (id, name) VALUES");
176
+
177
+
// Grab the columns from the block.
178
+
auto col1 = block[0]->As<ColumnUInt64>();
179
+
auto col2 = block[1]->As<ColumnString>();
180
+
181
+
// Add a couple of records to the block.
182
+
col1.Append(1);
183
+
col1.Append(2);
184
+
col2.Append("holden");
185
+
col2.Append("naomi");
186
+
187
+
// Send those records.
188
+
block.RefreshRowCount();
189
+
client->InsertData(block);
190
+
block.Clear();
191
+
192
+
// Add another record.
193
+
col1.Append(3);
194
+
col2.Append("amos");
195
+
196
+
// Send it and finish.
197
+
block.RefreshRowCount();
198
+
client->EndInsert(block);
199
+
200
+
// Free the block when done.
201
+
delete block;
202
+
```
203
+
160
204
## Thread-safety
161
205
⚠ Please note that `Client` instance is NOT thread-safe. I.e. you must create a separate `Client` for each thread or utilize some synchronization techniques. ⚠
0 commit comments