⌘+k ctrl+k
1.3 (稳定版)
搜索快捷键 cmd + k | ctrl + k
Node.js API

DuckDB Node.js(已弃用)客户端的最新版本是 1.3.2。

已弃用 旧的 DuckDB Node.js 包已弃用。请改用DuckDB Node Neo 包

duckdb 包为 DuckDB 提供了 Node.js API。此客户端的 API 与 SQLite Node.js 客户端在某种程度上兼容,以便于过渡。

初始化

加载包并创建一个数据库对象

const duckdb = require('duckdb');
const db = new duckdb.Database(':memory:'); // or a file name for a persistent DB

所有在数据库配置中描述的选项都可以(可选地)作为第二个参数提供给 Database 构造函数。第三个参数可以可选地提供,以获取有关给定选项的反馈。

const db = new duckdb.Database(':memory:', {
    "access_mode": "READ_WRITE",
    "max_memory": "512MB",
    "threads": "4"
}, (err) => {
  if (err) {
    console.error(err);
  }
});

运行查询

以下代码片段使用 Database.all() 方法运行一个简单查询。

db.all('SELECT 42 AS fortytwo', function(err, res) {
  if (err) {
    console.warn(err);
    return;
  }
  console.log(res[0].fortytwo)
});

其他可用方法包括 each(回调函数会为每一行调用),run(用于执行单个语句而不返回结果)和 exec(可以一次执行多个 SQL 命令,但也不返回结果)。所有这些命令都可以与预处理语句配合使用,将参数值作为附加参数传入。例如:

db.all('SELECT ?::INTEGER AS fortytwo, ?::VARCHAR AS hello', 42, 'Hello, World', function(err, res) {
  if (err) {
    console.warn(err);
    return;
  }
  console.log(res[0].fortytwo)
  console.log(res[0].hello)
});

连接

一个数据库可以有多个 Connection,这些连接通过 db.connect() 创建。

const con = db.connect();

您可以创建多个连接,每个连接都有自己的事务上下文。

Connection 对象还包含直接调用 run()all()each() 的简写方式,分别带参数和回调函数,例如:

con.all('SELECT 42 AS fortytwo', function(err, res) {
  if (err) {
    console.warn(err);
    return;
  }
  console.log(res[0].fortytwo)
});

预处理语句

从连接中,您可以使用 con.prepare() 创建预处理语句(且仅此而已)

const stmt = con.prepare('SELECT ?::INTEGER AS fortytwo');

要执行此语句,您可以在 stmt 对象上调用例如 all()

stmt.all(42, function(err, res) {
  if (err) {
    console.warn(err);
  } else {
    console.log(res[0].fortytwo)
  }
});

您也可以多次执行预处理语句。这例如对于用数据填充表格很有用。

con.run('CREATE TABLE a (i INTEGER)');
const stmt = con.prepare('INSERT INTO a VALUES (?)');
for (let i = 0; i < 10; i++) {
  stmt.run(i);
}
stmt.finalize();
con.all('SELECT * FROM a', function(err, res) {
  if (err) {
    console.warn(err);
  } else {
    console.log(res)
  }
});

prepare() 也可以接受一个回调函数,该函数将预处理语句作为参数。

const stmt = con.prepare('SELECT ?::INTEGER AS fortytwo', function(err, stmt) {
  stmt.all(42, function(err, res) {
    if (err) {
      console.warn(err);
    } else {
      console.log(res[0].fortytwo)
    }
  });
});

通过 Arrow 插入数据

Apache Arrow 可用于将数据插入 DuckDB,而无需进行复制。

const arrow = require('apache-arrow');
const db = new duckdb.Database(':memory:');

const jsonData = [
  {"userId":1,"id":1,"title":"delectus aut autem","completed":false},
  {"userId":1,"id":2,"title":"quis ut nam facilis et officia qui","completed":false}
];

// note; doesn't work on Windows yet
db.exec(`INSTALL arrow; LOAD arrow;`, (err) => {
    if (err) {
        console.warn(err);
        return;
    }

    const arrowTable = arrow.tableFromJSON(jsonData);
    db.register_buffer("jsonDataTable", [arrow.tableToIPC(arrowTable)], true, (err, res) => {
        if (err) {
            console.warn(err);
            return;
        }

        // `SELECT * FROM jsonDataTable` would return the entries in `jsonData`
    });
});

加载未签名扩展

要加载未签名扩展,请按如下方式实例化数据库:

db = new duckdb.Database(':memory:', {"allow_unsigned_extensions": "true"});

本节页面