SQLite#

稳定性: 1.1 - 积极开发中。

源代码: lib/sqlite.js

node:sqlite 模块方便使用 SQLite 数据库。 要访问它

import sqlite from 'node:sqlite';const sqlite = require('node:sqlite');

此模块仅在 node: 方案下可用。

以下示例展示了 node:sqlite 模块的基本用法,用于打开内存数据库,将数据写入数据库,然后将数据读回。

import { DatabaseSync } from 'node:sqlite';
const database = new DatabaseSync(':memory:');

// Execute SQL statements from strings.
database.exec(`
  CREATE TABLE data(
    key INTEGER PRIMARY KEY,
    value TEXT
  ) STRICT
`);
// Create a prepared statement to insert data into the database.
const insert = database.prepare('INSERT INTO data (key, value) VALUES (?, ?)');
// Execute the prepared statement with bound values.
insert.run(1, 'hello');
insert.run(2, 'world');
// Create a prepared statement to read data from the database.
const query = database.prepare('SELECT * FROM data ORDER BY key');
// Execute the prepared statement and log the result set.
console.log(query.all());
// Prints: [ { key: 1, value: 'hello' }, { key: 2, value: 'world' } ]'use strict';
const { DatabaseSync } = require('node:sqlite');
const database = new DatabaseSync(':memory:');

// Execute SQL statements from strings.
database.exec(`
  CREATE TABLE data(
    key INTEGER PRIMARY KEY,
    value TEXT
  ) STRICT
`);
// Create a prepared statement to insert data into the database.
const insert = database.prepare('INSERT INTO data (key, value) VALUES (?, ?)');
// Execute the prepared statement with bound values.
insert.run(1, 'hello');
insert.run(2, 'world');
// Create a prepared statement to read data from the database.
const query = database.prepare('SELECT * FROM data ORDER BY key');
// Execute the prepared statement and log the result set.
console.log(query.all());
// Prints: [ { key: 1, value: 'hello' }, { key: 2, value: 'world' } ]

类:DatabaseSync#

此类表示与 SQLite 数据库的单个 连接。 此类公开的所有 API 都是同步执行的。

new DatabaseSync(path[, options])#

  • path <string> | <Buffer> | <URL> 数据库的路径。 SQLite 数据库可以存储在文件中或完全 在内存中。 要使用文件支持的数据库,路径应该是文件路径。 要使用内存数据库,路径应该是特殊名称 ':memory:'
  • options <Object> 数据库连接的配置选项。 支持以下选项
    • open <boolean> 如果为 true,则数据库由构造函数打开。 当此值为 false 时,必须通过 open() 方法打开数据库。 默认: true
    • readOnly <boolean> 如果为 true,则以只读模式打开数据库。 如果数据库不存在,则打开它将失败。 默认: false
    • enableForeignKeyConstraints <boolean> 如果为 true,则启用外键约束。 建议这样做,但可以禁用它以与旧版数据库模式兼容。 可以在打开数据库后使用 PRAGMA foreign_keys 启用和禁用外键约束的强制执行。 默认: true
    • enableDoubleQuotedStringLiterals <boolean> 如果为 true,则 SQLite 将接受 双引号字符串字面量。 不建议这样做,但可以启用它以与旧版数据库模式兼容。 默认: false
    • allowExtension <boolean> 如果为 true,则启用 loadExtension SQL 函数和 loadExtension() 方法。 稍后可以调用 enableLoadExtension(false) 以禁用此功能。 默认: false
    • timeout <number> 以毫秒为单位的 繁忙超时。 这是 SQLite 在返回错误之前等待数据库锁释放的最长时间。 默认: 0

构造一个新的 DatabaseSync 实例。

database.aggregate(name, options)#

使用 SQLite 数据库注册一个新的聚合函数。 此方法是 sqlite3_create_window_function() 的包装器。

  • name <string> 要创建的 SQLite 函数的名称。
  • options <Object> 函数配置设置。
    • deterministic <boolean> 如果为 true,则在创建的函数上设置 SQLITE_DETERMINISTIC 标志。 默认: false
    • directOnly <boolean> 如果为 true,则在创建的函数上设置 SQLITE_DIRECTONLY 标志。 默认: false
    • useBigIntArguments <boolean> 如果为 true,则传递给 options.stepoptions.inverse 的整数参数将转换为 BigInt。 如果为 false,则整数参数将作为 JavaScript 数字传递。 默认: false
    • varargs <boolean> 如果为 true,则可以使用任意数量的参数(介于零和 SQLITE_MAX_FUNCTION_ARG 之间)调用 options.stepoptions.inverse。 如果为 false,则必须使用恰好 length 个参数调用 inversestep默认: false
    • start <number> | <string> | <null> | <Array> | <Object> | <Function> 聚合函数的身份值。 初始化聚合函数时使用此值。 当传递 <Function> 时,身份将是其返回值。
    • step <Function> 为聚合中的每一行调用的函数。 该函数接收当前状态和行值。 此函数的返回值应为新状态。
    • result <Function> 调用以获取聚合结果的函数。 该函数接收最终状态,应返回聚合结果。
    • inverse <Function> 提供此函数时,aggregate 方法将用作窗口函数。 该函数接收当前状态和删除的行值。 此函数的返回值应为新状态。

当用作窗口函数时,将多次调用 result 函数。

const { DatabaseSync } = require('node:sqlite');

const db = new DatabaseSync(':memory:');
db.exec(`
  CREATE TABLE t3(x, y);
  INSERT INTO t3 VALUES ('a', 4),
                        ('b', 5),
                        ('c', 3),
                        ('d', 8),
                        ('e', 1);
`);

db.aggregate('sumint', {
  start: 0,
  step: (acc, value) => acc + value,
});

db.prepare('SELECT sumint(y) as total FROM t3').get(); // { total: 21 }import { DatabaseSync } from 'node:sqlite';

const db = new DatabaseSync(':memory:');
db.exec(`
  CREATE TABLE t3(x, y);
  INSERT INTO t3 VALUES ('a', 4),
                        ('b', 5),
                        ('c', 3),
                        ('d', 8),
                        ('e', 1);
`);

db.aggregate('sumint', {
  start: 0,
  step: (acc, value) => acc + value,
});

db.prepare('SELECT sumint(y) as total FROM t3').get(); // { total: 21 }

database.close()#

关闭数据库连接。 如果数据库未打开,则会抛出异常。 此方法是 sqlite3_close_v2() 的包装器。

database.loadExtension(path)#

  • path <string> 要加载的共享库的路径。

将共享库加载到数据库连接中。此方法是对 sqlite3_load_extension() 的封装。构造 DatabaseSync 实例时,需要启用 allowExtension 选项。

database.enableLoadExtension(allow)#

  • allow <boolean> 是否允许加载扩展。

启用或禁用 loadExtension SQL 函数和 loadExtension() 方法。当构造时 allowExtensionfalse 时,出于安全原因,您无法启用加载扩展。

database.location([dbName])#

  • dbName <string> 数据库的名称。可以是 'main'(默认的主数据库)或使用 ATTACH DATABASE 添加的任何其他数据库。默认值: 'main'
  • 返回值: <string> | <null> 数据库文件的位置。 当使用内存数据库时,此方法返回 null。

此方法是对 sqlite3_db_filename() 的封装。

database.exec(sql)#

  • sql <string> 要执行的 SQL 字符串。

此方法允许执行一个或多个 SQL 语句,而不返回任何结果。 在执行从文件中读取的 SQL 语句时,此方法非常有用。 此方法是对 sqlite3_exec() 的封装。

database.function(name[, options], function)#

  • name <string> 要创建的 SQLite 函数的名称。
  • options <Object> 函数的可选配置设置。 支持以下属性
    • deterministic <boolean> 如果为 true,则在创建的函数上设置 SQLITE_DETERMINISTIC 标志。 默认: false
    • directOnly <boolean> 如果为 true,则在创建的函数上设置 SQLITE_DIRECTONLY 标志。 默认: false
    • useBigIntArguments <boolean> 如果为 true,则传递给 function 的整数参数将转换为 BigInt。 如果为 false,则整数参数将作为 JavaScript 数字传递。 默认值: false
    • varargs <boolean> 如果为 true,则可以调用 function 并传入任意数量的参数(介于零和 SQLITE_MAX_FUNCTION_ARG 之间)。 如果为 false,则必须使用精确的 function.length 参数来调用 function默认值: false
  • function <Function> 调用 SQLite 函数时要调用的 JavaScript 函数。 此函数的返回值应为有效的 SQLite 数据类型:请参阅JavaScript 和 SQLite 之间的数据类型转换。 如果返回值是 undefined,则结果默认为 NULL

此方法用于创建 SQLite 用户定义的函数。 此方法是对 sqlite3_create_function_v2() 的封装。

database.isOpen#

  • <boolean> 数据库当前是否已打开。

database.isTransaction#

database.open()#

打开 DatabaseSync 构造函数的 path 参数中指定的数据库。 仅当未通过构造函数打开数据库时,才应使用此方法。 如果数据库已打开,则会引发异常。

database.prepare(sql)#

将 SQL 语句编译为预处理语句。 此方法是对 sqlite3_prepare_v2() 的封装。

database.createSession([options])#

  • options <Object> 会话的配置选项。
    • table <string> 要跟踪更改的特定表。 默认情况下,会跟踪对所有表的更改。
    • db <string> 要跟踪的数据库的名称。 当使用 ATTACH DATABASE 添加多个数据库时,这非常有用。 默认值: 'main'
  • 返回值:<Session> 会话句柄。

创建会话并将其附加到数据库。 此方法是对 sqlite3session_create()sqlite3session_attach() 的封装。

database.applyChangeset(changeset[, options])#

  • changeset <Uint8Array> 二进制变更集或补丁集。
  • options <Object> 如何应用更改的配置选项。
    • filter <Function> 跳过当目标表名提供给此函数时,返回真值的更改。 默认情况下,会尝试所有更改。

    • onConflict <Function> 确定如何处理冲突的函数。 该函数接收一个参数,该参数可以是以下值之一

      • SQLITE_CHANGESET_DATA: DELETEUPDATE 更改不包含预期的 "before" 值。
      • SQLITE_CHANGESET_NOTFOUND: 不存在与 DELETEUPDATE 更改的主键匹配的行。
      • SQLITE_CHANGESET_CONFLICT: INSERT 更改导致重复的主键。
      • SQLITE_CHANGESET_FOREIGN_KEY: 应用更改会导致外键违规。
      • SQLITE_CHANGESET_CONSTRAINT: 应用更改会导致 UNIQUECHECKNOT NULL 约束违规。

      该函数应返回以下值之一

      • SQLITE_CHANGESET_OMIT: 省略冲突的更改。
      • SQLITE_CHANGESET_REPLACE: 使用冲突的更改替换现有值(仅在使用 SQLITE_CHANGESET_DATASQLITE_CHANGESET_CONFLICT 冲突时有效)。
      • SQLITE_CHANGESET_ABORT: 在冲突时中止并回滚数据库。

      如果在冲突处理程序中引发错误,或者处理程序返回任何其他值,则应用变更集会被中止并且数据库会被回滚。

      默认值: 返回 SQLITE_CHANGESET_ABORT 的函数。

  • 返回值:<boolean> 变更集是否成功应用而未被中止。

如果数据库未打开,则会引发异常。 此方法是对 sqlite3changeset_apply() 的封装。

const sourceDb = new DatabaseSync(':memory:');
const targetDb = new DatabaseSync(':memory:');

sourceDb.exec('CREATE TABLE data(key INTEGER PRIMARY KEY, value TEXT)');
targetDb.exec('CREATE TABLE data(key INTEGER PRIMARY KEY, value TEXT)');

const session = sourceDb.createSession();

const insert = sourceDb.prepare('INSERT INTO data (key, value) VALUES (?, ?)');
insert.run(1, 'hello');
insert.run(2, 'world');

const changeset = session.changeset();
targetDb.applyChangeset(changeset);
// Now that the changeset has been applied, targetDb contains the same data as sourceDb. 

database[Symbol.dispose]()#

稳定性:1 - 实验性

关闭数据库连接。 如果数据库连接已关闭,则此操作无效。

类: Session#

session.changeset()#

  • 返回值:<Uint8Array> 可以应用于其他数据库的二进制变更集。

检索包含自创建变更集以来所有更改的变更集。 可以多次调用。 如果数据库或会话未打开,则会引发异常。 此方法是对 sqlite3session_changeset() 的封装。

session.patchset()#

  • 返回值:<Uint8Array> 可以应用于其他数据库的二进制补丁集。

与上述方法类似,但生成更紧凑的补丁集。 请参阅 SQLite 文档中的 变更集和补丁集。 如果数据库或会话未打开,则会引发异常。 此方法是对 sqlite3session_patchset() 的封装。

session.close().#

关闭会话。 如果数据库或会话未打开,则会引发异常。 此方法是对 sqlite3session_delete() 的封装。

类: StatementSync#

此类表示单个 预处理语句。 无法通过其构造函数实例化此类。 相反,实例通过 database.prepare() 方法创建。 此类公开的所有 API 都会同步执行。

预处理语句是用于创建它的 SQL 的有效二进制表示形式。 预处理语句是可参数化的,并且可以使用不同的绑定值多次调用。 参数还可以提供针对 SQL 注入 攻击的保护。 因此,在处理用户输入时,预处理语句优于手工制作的 SQL 字符串。

statement.all([namedParameters][, ...anonymousParameters])#

  • namedParameters <Object> (可选) 用于绑定命名参数的对象。此对象的键用于配置映射。
  • ...anonymousParameters <null> | <number> | <bigint> | <string> | <Buffer> | <TypedArray> | <DataView> 零个或多个值,用于绑定匿名参数。
  • 返回: <Array> 对象数组。每个对象对应于执行预处理语句返回的行。每个对象的键和值对应于行的列名和值。

此方法执行预处理语句,并将所有结果作为对象数组返回。 如果预处理语句未返回任何结果,则此方法返回一个空数组。预处理语句的参数绑定使用namedParametersanonymousParameters中的值。

statement.columns()#

此方法用于检索有关预处理语句返回的列的信息。

statement.expandedSQL#

  • <string> 源 SQL 扩展为包含参数值。

预处理语句的源 SQL 文本,其中参数占位符替换为最近执行此预处理语句期间使用的值。 此属性是 sqlite3_expanded_sql() 的包装器。

statement.get([namedParameters][, ...anonymousParameters])#

  • namedParameters <Object> (可选) 用于绑定命名参数的对象。此对象的键用于配置映射。
  • ...anonymousParameters <null> | <number> | <bigint> | <string> | <Buffer> | <TypedArray> | <DataView> 零个或多个值,用于绑定匿名参数。
  • 返回: <Object> | <undefined> 一个对象,对应于执行预处理语句返回的第一行。对象的键和值对应于行的列名和值。如果数据库未返回任何行,则此方法返回 undefined

此方法执行预处理语句,并将第一个结果作为对象返回。如果预处理语句未返回任何结果,则此方法返回 undefined。预处理语句的参数绑定使用namedParametersanonymousParameters中的值。

statement.iterate([namedParameters][, ...anonymousParameters])#

  • namedParameters <Object> (可选) 用于绑定命名参数的对象。此对象的键用于配置映射。
  • ...anonymousParameters <null> | <number> | <bigint> | <string> | <Buffer> | <TypedArray> | <DataView> 零个或多个值,用于绑定匿名参数。
  • 返回: <Iterator> 对象的iterable迭代器。每个对象对应于执行预处理语句返回的行。每个对象的键和值对应于行的列名和值。

此方法执行预处理语句,并返回对象的迭代器。如果预处理语句未返回任何结果,则此方法返回一个空迭代器。预处理语句的参数绑定使用namedParametersanonymousParameters中的值。

statement.run([namedParameters][, ...anonymousParameters])#

此方法执行预处理语句,并返回一个对象,该对象总结了生成的结果更改。预处理语句的参数绑定使用namedParametersanonymousParameters中的值。

statement.setAllowBareNamedParameters(enabled)#

  • enabled <boolean> 启用或禁用对没有前缀字符的绑定命名参数的支持。

SQLite 参数的名称以一个前缀字符开头。 默认情况下,node:sqlite 要求在绑定参数时存在此前缀字符。 但是,除了美元符号字符外,这些前缀字符在使用对象键时还需要额外的引号。

为了提高人体工程学,此方法还可用于允许裸命名参数,这些参数在 JavaScript 代码中不需要前缀字符。启用裸命名参数时,需要注意以下几个注意事项

  • SQL 中仍然需要前缀字符。
  • JavaScript 中仍然允许前缀字符。 实际上,带前缀的名称将具有稍好的绑定性能。
  • 在同一预处理语句中使用歧义的命名参数(例如 $k@k)将导致异常,因为无法确定如何绑定裸名称。

statement.setAllowUnknownNamedParameters(enabled)#

  • enabled <boolean> 启用或禁用对未知命名参数的支持。

默认情况下,如果在绑定参数时遇到未知名称,则会引发异常。 此方法允许忽略未知的命名参数。

statement.setReadBigInts(enabled)#

  • enabled <boolean> 启用或禁用在从数据库读取 INTEGER 字段时使用 BigInt

从数据库读取时,SQLite INTEGER 默认映射到 JavaScript 数字。 但是,SQLite INTEGER 可以存储大于 JavaScript 数字可以表示的值。 在这种情况下,可以使用此方法使用 JavaScript BigInt 读取 INTEGER 数据。 此方法对数据库写入操作没有影响,在数据库写入操作中,始终支持数字和 BigInt

statement.sourceSQL#

  • <string> 用于创建此预处理语句的源 SQL。

预处理语句的源 SQL 文本。此属性是 sqlite3_sql() 的包装器。

JavaScript 和 SQLite 之间的类型转换#

当 Node.js 写入或读取 SQLite 时,需要在 JavaScript 数据类型和 SQLite 的 数据类型之间进行转换。 因为 JavaScript 支持比 SQLite 更多的数据类型,所以只支持 JavaScript 类型的一个子集。 尝试将不支持的数据类型写入 SQLite 将导致异常。

SQLiteJavaScript
NULL<null>
INTEGER<number><bigint>
REAL<number>
TEXT<string>
BLOB<TypedArray><DataView>

sqlite.backup(sourceDb, path[, options])#

  • sourceDb <DatabaseSync> 要备份的数据库。源数据库必须是打开的。
  • path <string> | <Buffer> | <URL> 将创建备份的路径。 如果文件已存在,内容将被覆盖。
  • options <Object> 备份的可选配置。 支持以下属性
    • source <string> 源数据库的名称。 这可以是 'main' (默认主数据库) 或使用 ATTACH DATABASE 添加的任何其他数据库。默认值: 'main'
    • target <string> 目标数据库的名称。 这可以是 'main' (默认主数据库) 或使用 ATTACH DATABASE 添加的任何其他数据库。默认值: 'main'
    • rate <number> 在备份的每个批次中传输的页数。默认值: 100
    • progress <Function> 回调函数,将被调用,参数为复制的页数和总页数。
  • 返回: <Promise> 一个 promise,在备份完成时 resolve,如果发生错误则 reject。

此方法进行数据库备份。此方法抽象了 sqlite3_backup_init()sqlite3_backup_step()sqlite3_backup_finish() 函数。

备份的数据库可以在备份过程中正常使用。来自同一连接 - 相同的 <DatabaseSync> - 对象的更改将立即反映在备份中。 但是,来自其他连接的更改将导致备份过程重新启动。

const { backup, DatabaseSync } = require('node:sqlite');

(async () => {
  const sourceDb = new DatabaseSync('source.db');
  const totalPagesTransferred = await backup(sourceDb, 'backup.db', {
    rate: 1, // Copy one page at a time.
    progress: ({ totalPages, remainingPages }) => {
      console.log('Backup in progress', { totalPages, remainingPages });
    },
  });

  console.log('Backup completed', totalPagesTransferred);
})();import { backup, DatabaseSync } from 'node:sqlite';

const sourceDb = new DatabaseSync('source.db');
const totalPagesTransferred = await backup(sourceDb, 'backup.db', {
  rate: 1, // Copy one page at a time.
  progress: ({ totalPages, remainingPages }) => {
    console.log('Backup in progress', { totalPages, remainingPages });
  },
});

console.log('Backup completed', totalPagesTransferred);

sqlite.constants#

一个对象,包含 SQLite 操作常用的常量。

SQLite 常量#

以下常量由 sqlite.constants 对象导出。

冲突解决常量#

以下常量之一可用作传递给 database.applyChangeset()onConflict 冲突解决处理程序的参数。 另请参阅 SQLite 文档中的 传递给冲突处理程序的常量

常量 描述
SQLITE_CHANGESET_DATA 如果数据库中存在具有所需 PRIMARY KEY 字段的行,但在更新修改的一个或多个其他(非主键)字段不包含预期的“before”值时,将使用此常量调用冲突处理程序,以处理 DELETE 或 UPDATE 更改。
SQLITE_CHANGESET_NOTFOUND 如果数据库中不存在具有所需 PRIMARY KEY 字段的行,则使用此常量调用冲突处理程序,以处理 DELETE 或 UPDATE 更改。
SQLITE_CHANGESET_CONFLICT 如果操作将导致重复的主键值,则在处理 INSERT 更改时,此常量将传递给冲突处理程序。
SQLITE_CHANGESET_CONSTRAINT 如果启用了外键处理,并且应用更改集后数据库处于包含外键违规的状态,则在提交更改集之前,将使用此常量精确地调用冲突处理程序一次。 如果冲突处理程序返回 SQLITE_CHANGESET_OMIT,则提交更改,包括导致外键约束违反的更改。 或者,如果它返回 SQLITE_CHANGESET_ABORT,则回滚更改集。
SQLITE_CHANGESET_FOREIGN_KEY 如果在应用更改时发生任何其他约束违反(即 UNIQUE、CHECK 或 NOT NULL 约束),则会使用此常量调用冲突处理程序。

以下常量之一必须从传递给 database.applyChangeset()onConflict 冲突解决处理程序返回。 另请参阅 SQLite 文档中的 从冲突处理程序返回的常量

常量 描述
SQLITE_CHANGESET_OMIT 省略冲突的更改。
SQLITE_CHANGESET_REPLACE 冲突的更改替换现有值。 请注意,只有当冲突类型为 SQLITE_CHANGESET_DATASQLITE_CHANGESET_CONFLICT 时,才能返回此值。
SQLITE_CHANGESET_ABORT 当更改遇到冲突并回滚数据库时中止。