
TDengine Node.js 连接器入门指南
本文面向 TDengine 初学者,目标是让你在 5~10 分钟内完成:安装连接器 → 建立连接 → 建库建表 → 写入 → 查询,并掌握连接器的基本使用方式与常见问题排查。
说明:TDengine 官方 Node.js 连接器为
@tdengine/websocket,通过taosAdapter的 WebSocket 接口连接 TDengine。
1. 连接方式
@tdengine/websocket 连接器使用 WebSocket 连接 方式,通过 taosAdapter 的 WebSocket 接口访问 TDengine。这种方式依赖轻量,在并发和 IO 密集场景下表现优异。
连接方式的详细介绍见:
2. 环境准备
在运行示例前,请确认:
- TDengine 服务端已启动:确保你的程序能访问到 TDengine 服务。
- taosAdapter 已启动 :
@tdengine/websocket依赖taosAdapter的 WebSocket 服务(默认端口6041)。 - Node.js 版本:确保已安装 Node.js 14 及以上版本。
检查 Node.js 版本:
bash
node --version
检查 taosAdapter 服务状态:
bash
# Linux/macOS
systemctl status taosadapter
# 或直接测试 WebSocket 接口是否可访问
curl -i -N -d "show databases" -u root:taosdata http://localhost:6041/rest/sql
3. 安装连接器
使用 npm 安装:
bash
npm install @tdengine/websocket
或使用 yarn:
bash
yarn add @tdengine/websocket
4. 第一个程序:建库建表、写入、查询
下面是一个"最小可运行"示例,涵盖了 TDengine 的基本操作。
4.1 完整示例代码
创建文件 quickstart.js:
javascript
const taos = require("@tdengine/websocket");
async function main() {
let wsSql = null;
const host = "127.0.0.1";
const port = 6041;
try {
// 1. 建立连接
console.log("正在连接 TDengine...");
let url = `ws://${host}:${port}`;
let conf = new taos.WSConfig(url);
conf.setUser("root");
conf.setPwd("taosdata");
wsSql = await taos.sqlConnect(conf);
console.log("✓ 连接成功");
// 2. 创建数据库
console.log("\n创建数据库...");
await wsSql.exec("CREATE DATABASE IF NOT EXISTS demo");
console.log("✓ 数据库创建成功");
// 3. 使用数据库
await wsSql.exec("USE demo");
// 4. 创建超级表
console.log("\n创建超级表...");
await wsSql.exec(
"CREATE STABLE IF NOT EXISTS meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (location BINARY(64), groupId INT)"
);
console.log("✓ 超级表创建成功");
// 5. 创建子表并插入数据
console.log("\n插入数据...");
await wsSql.exec(
"INSERT INTO d1001 USING meters TAGS('California.SanFrancisco', 1) VALUES (NOW, 10.3, 219, 0.31)"
);
await wsSql.exec(
"INSERT INTO d1002 USING meters TAGS('California.LosAngeles', 2) VALUES (NOW, 12.6, 218, 0.33)"
);
console.log("✓ 数据插入成功");
// 6. 查询数据
console.log("\n查询数据...");
let wsRows = await wsSql.query("SELECT * FROM meters");
// 获取列信息
let meta = wsRows.getMeta();
console.log("\n列信息:");
meta.forEach((col) => {
console.log(` ${col.name} (${col.type})`);
});
// 遍历结果集
console.log("\n查询结果:");
while (await wsRows.next()) {
let row = wsRows.getData();
console.log(row);
}
// 关闭结果集
await wsRows.close();
console.log("\n✓ 程序执行完成");
} catch (err) {
console.error("❌ 错误:", err.message);
if (err.code) {
console.error(" 错误码:", err.code);
}
} finally {
// 7. 关闭连接
if (wsSql) {
await wsSql.destroyed();
console.log("✓ 连接已关闭");
}
}
}
main();
4.2 运行示例
bash
node quickstart.js
4.3 预期输出
如果一切正常,你会看到类似以下输出:
正在连接 TDengine...
✓ 连接成功
创建数据库...
✓ 数据库创建成功
创建超级表...
✓ 超级表创建成功
插入数据...
✓ 数据插入成功
查询数据...
列信息:
ts (TIMESTAMP)
current (FLOAT)
voltage (INT)
phase (FLOAT)
location (BINARY)
groupId (INT)
查询结果:
[ 2026-01-14T08:30:45.123Z, 10.3, 219, 0.31, 'California.SanFrancisco', 1 ]
[ 2026-01-14T08:30:45.456Z, 12.6, 218, 0.33, 'California.LosAngeles', 2 ]
✓ 程序执行完成
✓ 连接已关闭
5. 代码解析
5.1 建立连接
javascript
const taos = require("@tdengine/websocket");
// 配置连接参数
let url = 'ws://127.0.0.1:6041'; // taosAdapter 的 WebSocket 地址
let conf = new taos.WSConfig(url);
conf.setUser('root'); // 用户名
conf.setPwd('taosdata'); // 密码
conf.setDb('demo'); // 可选:指定默认数据库
// 建立连接
let wsSql = await taos.sqlConnect(conf);
连接参数说明:
url:WebSocket 地址,格式为ws://host:portuser:数据库用户名,默认为rootpassword:数据库密码,默认为taosdatadatabase:可选,指定默认数据库
5.2 执行 SQL
Node.js 连接器提供两个主要方法:
执行非查询 SQL(exec) :用于执行 CREATE、INSERT、DROP 等不返回数据集的 SQL。
javascript
let result = await wsSql.exec('CREATE DATABASE IF NOT EXISTS test');
console.log('影响的行数:', result.affectRows);
console.log('执行时长:', result.timing, 'ms');
执行查询 SQL(query) :用于执行 SELECT 等返回数据集的 SQL。
javascript
let wsRows = await wsSql.query('SELECT * FROM meters');
// 获取列信息
let meta = wsRows.getMeta();
// 遍历结果
while (await wsRows.next()) {
let row = wsRows.getData();
console.log(row);
}
// 必须关闭结果集
await wsRows.close();
5.3 数据类型映射
TDengine 数据类型与 Node.js 类型的对应关系:
| TDengine 类型 | Node.js 类型 | 说明 |
|---|---|---|
| TIMESTAMP | bigint | 时间戳(毫秒) |
| INT | number | 整数 |
| BIGINT | bigint | 大整数 |
| FLOAT | number | 单精度浮点 |
| DOUBLE | number | 双精度浮点 |
| BINARY | string | 二进制字符串 |
| NCHAR | string | Unicode 字符串 |
| BOOL | boolean | 布尔值 |
| JSON | string | JSON 字符串 |
完整映射表见 API 参考文档。
5.4 错误处理
使用 try-catch 捕获异常:
javascript
try {
await wsSql.exec('SELECT * FROM non_existent_table');
} catch (err) {
console.error('错误信息:', err.message);
console.error('错误码:', err.code);
}
常见错误码:
- 参考 TDengine 错误码
5.5 关闭连接
使用完连接后,务必关闭以释放资源:
javascript
await wsSql.destroyed();
6. 进阶:参数绑定写入
参数绑定(Prepared Statement)可以显著提升批量写入性能,推荐用于高性能写入场景。
6.1 基本用法
javascript
const taos = require("@tdengine/websocket");
async function stmtExample() {
let wsSql = null;
let stmt = null;
try {
// 建立连接
let conf = new taos.WSConfig('ws://127.0.0.1:6041');
conf.setUser('root');
conf.setPwd('taosdata');
wsSql = await taos.sqlConnect(conf);
// 准备数据库和表
await wsSql.exec('CREATE DATABASE IF NOT EXISTS demo');
await wsSql.exec('USE demo');
await wsSql.exec(
'CREATE STABLE IF NOT EXISTS meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (location BINARY(64), groupId INT)'
);
// 1. 初始化 stmt 对象
stmt = await wsSql.stmtInit();
// 2. 准备 SQL(使用 ? 作为占位符)
await stmt.prepare('INSERT INTO ? USING meters TAGS(?, ?) VALUES(?, ?, ?, ?)');
// 3. 设置表名
await stmt.setTableName('d1003');
// 4. 设置 TAGS
let tagsParams = new taos.StmtBindParams();
tagsParams.setVarchar(['California.SanDiego']);
tagsParams.setInt([3]);
await stmt.setTags(tagsParams);
// 5. 绑定数据(可以批量绑定多行)
let bindParams = new taos.StmtBindParams();
bindParams.setTimestamp([Date.now(), Date.now() + 1000]);
bindParams.setFloat([10.8, 11.2]);
bindParams.setInt([220, 221]);
bindParams.setFloat([0.35, 0.36]);
await stmt.bind(bindParams);
// 6. 提交批次
await stmt.batch();
// 7. 执行写入
await stmt.exec();
console.log('写入条数:', stmt.getLastAffected());
} catch (err) {
console.error('错误:', err);
} finally {
// 关闭 stmt 和连接
if (stmt) await stmt.close();
if (wsSql) await wsSql.destroyed();
}
}
stmtExample();
6.2 参数绑定的优势
- 高性能:批量写入时性能可提升数倍
- 防注入:避免 SQL 注入风险
- 代码清晰:数据与 SQL 分离,更易维护
6.3 绑定类型方法
StmtBindParams 类提供了以下方法来绑定不同类型的数据:
javascript
let params = new taos.StmtBindParams();
// 数值类型
params.setBoolean([true, false]);
params.setTinyInt([1, 2]);
params.setSmallInt([100, 200]);
params.setInt([1000, 2000]);
params.setBigint([10000n, 20000n]);
params.setFloat([1.1, 2.2]);
params.setDouble([1.111, 2.222]);
// 字符串类型
params.setVarchar(['hello', 'world']);
params.setBinary([Buffer.from('data1'), Buffer.from('data2')]);
params.setNchar(['中文', '测试']);
// 时间戳
params.setTimestamp([Date.now(), Date.now() + 1000]);
完整 API 参考见 参数绑定文档。
7. 数据订阅(TMQ)
TDengine 支持数据订阅功能,类似 Kafka 的消息队列,可以实时消费写入的数据。
7.1 订阅示例
javascript
const taos = require("@tdengine/websocket");
async function tmqExample() {
let consumer = null;
try {
// 1. 创建消费者配置
let configMap = new Map([
[taos.TMQConstants.GROUP_ID, 'group1'],
[taos.TMQConstants.CLIENT_ID, 'client1'],
[taos.TMQConstants.WS_URL, 'ws://127.0.0.1:6041'],
[taos.TMQConstants.CONNECT_USER, 'root'],
[taos.TMQConstants.CONNECT_PASS, 'taosdata'],
[taos.TMQConstants.AUTO_OFFSET_RESET, 'earliest'],
[taos.TMQConstants.ENABLE_AUTO_COMMIT, 'true'],
[taos.TMQConstants.AUTO_COMMIT_INTERVAL_MS, '1000']
]);
// 2. 创建消费者
consumer = await taos.newConsumer(configMap);
// 3. 订阅主题(需要先在 TDengine 中创建主题)
await consumer.subscribe(['topic_meters']);
console.log('开始消费数据...');
// 4. 循环拉取数据
for (let i = 0; i < 10; i++) {
let res = await consumer.poll(1000); // 超时时间 1000ms
for (let [topic, taosResult] of res) {
console.log(`主题: ${topic}`);
let wsRows = taosResult;
while (await wsRows.next()) {
console.log('数据:', wsRows.getData());
}
await wsRows.close();
}
}
// 5. 提交消费位移
await consumer.commit();
} catch (err) {
console.error('错误:', err);
} finally {
// 6. 关闭消费者
if (consumer) {
await consumer.unsubscribe();
await consumer.close();
}
}
}
tmqExample();
7.2 创建主题
在使用订阅前,需要先在 TDengine 中创建主题:
sql
-- 创建主题
CREATE TOPIC topic_meters AS SELECT * FROM demo.meters;
完整订阅 API 参考见 数据订阅文档。
8. 常见问题排查
8.1 连接失败
症状:
Error: Unable to establish connection
原因和解决方案:
-
taosAdapter 未启动
bash# Linux/macOS systemctl start taosadapter systemctl status taosadapter -
端口不正确
- 默认 WebSocket 端口为
6041 - 检查 taosAdapter 配置文件中的端口设置
- 默认 WebSocket 端口为
-
防火墙阻止
bash# Linux 开放端口 sudo firewall-cmd --zone=public --add-port=6041/tcp --permanent sudo firewall-cmd --reload -
用户名或密码错误
- 确认使用正确的用户名和密码
- 默认用户名:
root,密码:taosdata
8.2 FQDN 配置问题
症状:
Error: Unable to resolve FQDN
解决方案:
确保 TDengine 服务端的 FQDN 配置正确。参考:
8.3 时区问题
症状:时间戳显示不正确。
解决方案:
设置 taosAdapter 所在机器的 taosc 客户端时区配置:
bash
# 在 taos.cfg 中设置
timezone=Asia/Shanghai
8.4 查询结果为空
检查项:
-
确认数据已正确插入
javascriptlet result = await wsSql.exec('INSERT INTO d1001 VALUES (NOW, 10.3, 219, 0.31)'); console.log('影响行数:', result.affectRows); -
确认使用了正确的数据库
javascriptawait wsSql.exec('USE demo'); -
确认表名和列名拼写正确
8.5 Node.js 版本不兼容
症状:
Error: Package subpath './package.json' is not defined
解决方案:
升级 Node.js 到 14 或更高版本:
bash
node --version # 检查当前版本
nvm install 18 # 使用 nvm 安装 Node.js 18
nvm use 18 # 切换到 Node.js 18
9. 最佳实践
9.1 连接管理
- 使用连接池:在高并发场景下,考虑实现连接池复用连接
- 及时关闭 :使用完连接后务必调用
destroyed()释放资源 - 异常处理 :始终使用
try-catch-finally确保连接被正确关闭
javascript
async function withConnection(callback) {
let wsSql = null;
try {
let conf = new taos.WSConfig('ws://127.0.0.1:6041');
conf.setUser('root');
conf.setPwd('taosdata');
wsSql = await taos.sqlConnect(conf);
return await callback(wsSql);
} finally {
if (wsSql) await wsSql.destroyed();
}
}
// 使用
await withConnection(async (conn) => {
await conn.exec('CREATE DATABASE IF NOT EXISTS test');
});
9.2 批量写入
使用参数绑定进行批量写入,可获得最佳性能:
javascript
// 准备批量数据
let timestamps = [];
let currents = [];
let voltages = [];
for (let i = 0; i < 1000; i++) {
timestamps.push(Date.now() + i * 1000);
currents.push(Math.random() * 20);
voltages.push(220 + Math.floor(Math.random() * 10));
}
// 批量绑定和写入
let params = new taos.StmtBindParams();
params.setTimestamp(timestamps);
params.setFloat(currents);
params.setInt(voltages);
await stmt.bind(params);
await stmt.batch();
await stmt.exec();
9.3 查询优化
-
限制返回数据量 :使用
LIMIT子句javascriptlet wsRows = await wsSql.query('SELECT * FROM meters LIMIT 1000'); -
使用时间范围过滤:利用时间索引提升性能
javascriptlet wsRows = await wsSql.query( "SELECT * FROM meters WHERE ts >= NOW - 1h" ); -
及时关闭结果集:遍历完成后立即关闭
javascriptwhile (await wsRows.next()) { // 处理数据 } await wsRows.close(); // 及时关闭
10. 更多资源
10.1 示例代码
GitHub 上的完整示例:
10.2 社区支持
11. 总结
通过本指南,你已经学会了:
✓ 安装和配置 Node.js 连接器
✓ 建立连接并执行基本 SQL 操作
✓ 使用参数绑定实现高性能写入
✓ 使用数据订阅功能
✓ 常见问题的排查和解决
下一步建议:
- 阅读 完整 API 参考文档 了解更多高级功能
- 查看 GitHub 示例代码 学习实际应用
- Node.js 连接器 开源仓库地址
- 根据你的业务需求设计合适的数据模型
- 在生产环境中优化连接和查询性能
如有问题,欢迎在 GitHub 提交 Issue 或参与社区讨论!
关于 TDengine
TDengine 专为物联网IoT平台、工业大数据平台设计。其中,TDengine TSDB 是一款高性能、分布式的时序数据库(Time Series Database),同时它还带有内建的缓存、流式计算、数据订阅等系统功能;TDengine IDMP 是一款AI原生工业数据管理平台,它通过树状层次结构建立数据目录,对数据进行标准化、情景化,并通过 AI 提供实时分析、可视化、事件管理与报警等功能。