⌘+k ctrl+k
1.3 (稳定版)
搜索快捷键 cmd + k | ctrl + k
追加器

追加器可用于将批量数据加载到 DuckDB 数据库中。它目前在 C、C++、Go、Java 和 Rust API 中可用。追加器与连接绑定,并在追加时使用该连接的事务上下文。一个追加器始终将数据追加到数据库文件中的单个表中。

C++ API 中,追加器的工作方式如下

DuckDB db;
Connection con(db);
// create the table
con.Query("CREATE TABLE people (id INTEGER, name VARCHAR)");
// initialize the appender
Appender appender(con, "people");

AppendRow 函数是追加数据最简单的方法。它使用递归模板,允许您在一次函数调用中放入单行的所有值,如下所示

appender.AppendRow(1, "Mark");

行也可以使用 BeginRowEndRowAppend 方法单独构建。这由 AppendRow 在内部完成,因此具有相同的性能特征。

appender.BeginRow();
appender.Append<int32_t>(2);
appender.Append<string>("Hannes");
appender.EndRow();

出于性能原因,添加到追加器中的任何值都会在插入数据库系统之前被缓存。这意味着在追加过程中,行可能不会立即在系统中可见。当追加器超出作用域或调用 appender.Close() 时,缓存会自动刷新。也可以使用 appender.Flush() 方法手动刷新缓存。在调用 FlushClose 之后,所有数据都已写入数据库系统。

日期、时间和时间戳

尽管数字和字符串相当一目了然,但日期、时间和时间戳需要一些解释。它们可以直接使用 duckdb::Dateduckdb::Timeduckdb::Timestamp 提供的方法进行追加。它们也可以使用内部的 duckdb::Value 类型进行追加,但是,这会增加一些额外的开销,应尽可能避免。

下面是一个简短的示例

con.Query("CREATE TABLE dates (d DATE, t TIME, ts TIMESTAMP)");
Appender appender(con, "dates");

// construct the values using the Date/Time/Timestamp types
// (this is the most efficient approach)
appender.AppendRow(
    Date::FromDate(1992, 1, 1),
    Time::FromTime(1, 1, 1, 0),
    Timestamp::FromDatetime(Date::FromDate(1992, 1, 1), Time::FromTime(1, 1, 1, 0))
);
// construct duckdb::Value objects
appender.AppendRow(
    Value::DATE(1992, 1, 1),
    Value::TIME(1, 1, 1, 0),
    Value::TIMESTAMP(1992, 1, 1, 1, 1, 1, 0)
);

提交频率

默认情况下,追加器每 204,800 行执行一次提交。您可以通过显式使用事务,并用 BEGIN TRANSACTIONCOMMIT 语句包围您的批次 AppendRow 调用来更改此设置。

处理约束冲突

如果追加器遇到 PRIMARY KEY 冲突或 UNIQUE 约束冲突,它将失败并返回以下错误

Constraint Error:
PRIMARY KEY or UNIQUE constraint violated: duplicate key "..."

在这种情况下,整个追加操作失败,并且不会插入任何行。

其他客户端中的追加器支持

追加器在以下客户端 API 中也可用