建立连接
TDengine TSDB 提供了丰富的应用程序开发接口。为便于用户快速开发应用,它支持多种编程语言的连接器,其中官方连接器包括 C/C++、Java、Python、Go、Node.js、C# 和 Rust;社区开发者也贡献了多个非官方连接器,例如 ADO.NET、Lua 和 PHP 连接器。这些连接器支持通过原生接口和 WebSocket 接口连接 TDengine TSDB 集群。另外,用户还可以直接调用 taosAdapter 提供的 REST API 接口访问 TDengine TSDB,进行数据写入和查询操作。
连接方式
下图为 TDengine TSDB 客户端和服务端连接方式的架构图:

如上面的架构图所示,我们有三种方式来访问 TDengine TSDB:
- WebSocket 连接:通过连接器使用 taosAdapter 组件提供的 WebSocket API 建立与 taosd 的连接,这种连接方式下文中简称“WebSocket 连接”。 推荐使用 WebSocket 连接。
- 原生连接:通过连接器使用客户端驱动程序 taosc 直接与服务端程序 taosd 建立连接,这种连接方式下文中简称“原生连接”。
- REST API:不使用连接器,通过 HTTP 客户端直接调用 taosAdapter 组件提供的 REST API 建立与 taosd 的连接,这种连接方式下文中简称“REST API”。
备注:客户端驱动程序 taosc 包含了 C 原生和 WebSocket 连接器,使用 C/C++ 语言开发的应用都需要依赖客户端驱动程序 taosc。
对于 WebSocket 连接和原生连接,连接器都提供了相同或相似的 API 操作数据库,只是初始化连接的方式稍有不同,用户在使用上不会感到什么差别。 各种连接方式和各语言连接器支持情况请参考 连接器功能特性。
关键不同点在于:
- 使用 原生连接,需要保证客户端的驱动程序 taosc 和服务端的 TDengine TSDB 版本保持一致。
- 使用 WebSocket 连接,除 C/C++ 和 ODBC 连接器外,用户无需安装客户端驱动程序 taosc。即使依赖客户端驱动程序 taosc,也无需保证其和服务端的 TDengine TSDB 版本保持一致。
- 连接云服务实例,必须使用 WebSocket 连接。
- REST API 仅提供执行 SQL 功能,不支持参数绑定和数据订阅。
安装客户端驱动 taosc
如果选择原生连接,而且应用程序不在 TDengine TSDB 同一台服务器上运行,你需要先安装客户端驱动,否则可以跳过此一步。为避免客户端驱动和服务端不兼容,请使用一致的版本。
安装步骤
- Linux
- Windows
- macOS
- 下载客户端安装包
-
解压缩软件包
将软件包放置在当前用户可读写的任意目录下,然后执行下面的命令:
tar -xzvf tdengine-tsdb-oss-client-3.3.8.8-linux-x64.tar.gz其中 VERSION 需要替换为实际版本的字符串。 -
执行安装脚本
解压软件包之后,会在解压目录下看到以下文件 (目录):
- install_client.sh:安装脚本,用于应用驱动程序
- package.tar.gz:应用驱动安装包
- driver:TDengine 应用驱动 driver
- examples: 各种编程语言的示例程序 (c/C#/go/JDBC/MATLAB/python/R) 运行 install_client.sh 进行安装。
-
配置 taos.cfg
编辑
taos.cfg文件(默认路径/etc/taos/taos.cfg),将firstEP修改为 TDengine 服务器的 End Point,例如:h1.tdengine.com:6030
- 如本机没有部署 TDengine 服务,仅安装了应用驱动,则
taos.cfg中仅需配置firstEP,无需在本机配置FQDN。 - 为防止与服务器端连接时出现“Unable to resolve FQDN”错误,建议确认本机的
/etc/hosts文件已经配置了服务器正确的 FQDN 值,或配置好了 DNS 服务。
- 下载客户端安装包
-
执行安装程序,按提示选择默认值,完成安装
-
安装路径
默认安装路径为:C:\TDengine,其中包括以下文件 (目录):
- taos.exe:TDengine CLI 命令行程序
- taosadapter.exe:提供 RESTful 服务和接受其他多种软件写入请求的服务端可执行文件
- taosBenchmark.exe:TDengine 测试程序
- cfg : 配置文件目录
- driver: 应用驱动动态链接库
- examples: 示例程序 bash/C/C#/go/JDBC/Python/Node.js
- include: 头文件
- log : 日志文件
- unins000.exe: 卸载程序
-
配置 taos.cfg
编辑 taos.cfg 文件(默认路径 C:\TDengine\cfg\taos.cfg),将 firstEP 修改为 TDengine 服务器的 End Point,例如:
h1.tdengine.com:6030。
- 如利用 FQDN 连接服务器,必须确认本机网络环境 DNS 已配置好,或在 hosts 文件中添加 FQDN 寻址记录,如编辑 C:\Windows\system32\drivers\etc\hosts,添加类似如下的记录:
192.168.1.99 h1.taos.com - 卸载:运行 unins000.exe 可卸载 TDengine 应用驱动。
- 下载客户端安装包
-
执行安装程序,按提示选择默认值,完成安装。如果安装被阻止,可以右键或者按 Ctrl 点击安装包,选择
打开。 -
配置 taos.cfg
编辑
taos.cfg文件(默认路径/etc/taos/taos.cfg),将firstEP修改为 TDengine 服务器的 End Point,例如:h1.tdengine.com:6030
- 如本机没有部署 TDengine 服务,仅安装了应用驱动,则
taos.cfg中仅需配置firstEP,无需在本机配置FQDN。 - 为防止与服务器端连接时出现“Unable to resolve FQDN”错误,建议确认本机的
/etc/hosts文件已经配置了服务器正确的 FQDN 值,或配置好了 DNS 服务。
安装验证
以上安装和配置完成后,并确认 TDengine TSDB 服务已经正常启动运行,此时可以执行安装包里带有的 TDengine TSDB 命令行程序 taos 进行登录。
- Linux
- Windows
- macOS
在 Linux shell 下直接执行 taos 连接到 TDengine 服务,进入到 TDengine CLI 界面,示例如下:
$ taos
taos> show databases;
name |
=================================
information_schema |
performance_schema |
db |
Query OK, 3 rows in database (0.019154s)
taos>
在 cmd 下进入到 C:\TDengine 目录下直接执行 taos.exe,连接到 TDengine 服务,进入到 TDengine CLI 界面,示例如下:
taos> show databases;
name | create_time | vgroups | ntables | replica | strict | duration | keep | buffer | pagesize | pages | minrows | maxrows | comp | precision | status | retention | single_stable | cachemodel | cachesize | wal_level | wal_fsync_period | wal_retention_period | wal_retention_size |
===============================================================================================================================================================================================================================================================================================================================================================================================================================
information_schema | NULL | NULL | 14 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | ready | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL |
performance_schema | NULL | NULL | 3 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | ready | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL |
test | 2022-08-04 16:46:40.506 | 2 | 0 | 1 | off | 14400m | 5256000m,5256000m,5256000m | 96 | 4 | 256 |
100 | 4096 | 2 | ms | ready | NULL | false | none | 1 | 1 | 3000 | 0 | 0 | 0 | 0 |
Query OK, 3 rows in database (0.123000s)
taos>
在 macOS shell 下直接执行 taos 连接到 TDengine 服务,进入到 TDengine CLI 界面,示例如下:
$ taos
taos> show databases;
name |
=================================
information_schema |
performance_schema |
db |
Query OK, 3 rows in database (0.019154s)
taos>
安装连接器
- Java
- Python
- Go
- Rust
- Node.js
- C#
- C
- REST API
如果使用 Maven 管理项目,只需在 pom.xml 中加入以下依赖。
<dependency>
<groupId>com.taosdata.jdbc</groupId>
<artifactId>taos-jdbcdriver</artifactId>
<version>3.7.8</version>
</dependency>
-
安装前准备
- 安装 Python。新近版本 taospy 包要求 Python 3.6.2+。早期版本 taospy 包要求 Python 3.7+。taos-ws-py 包要求 Python 3.7+。如果系统上还没有 Python 可参考 Python BeginnersGuide 安装。
- 安装 pip。大部分情况下 Python 的安装包都自带了 pip 工具,如果没有请参考 pip documentation 安装。
- 如果使用原生连接,还需 安装客户端驱动。客户端软件包含了 TDengine TSDB 客户端动态链接库 (libtaos.so 或 taos.dll) 和 TDengine TSDB CLI。
-
使用 pip 安装
-
卸载旧版本
如果以前安装过旧版本的 Python 连接器,请提前卸载。
pip3 uninstall taos taospy
pip3 uninstall taos taos-ws-py -
安装
taospy-
最新版本
pip3 install taospy -
指定某个特定版本安装
pip3 install taospy==2.8.6 -
从 GitHub 安装
pip3 install git+https://github.com/taosdata/taos-connector-python.git备注此安装包为原生连接器
-
-
安装
taos-ws-pypip3 install taos-ws-py备注此安装包为 WebSocket 连接器
-
同时安装
taospy和taos-ws-pypip3 install taospy[ws]
-
-
安装验证
- 原生连接
- WebSocket 连接
对于原生连接,需要验证客户端驱动和 Python 连接器本身是否都正确安装。如果能成功导入
taos模块,则说明已经正确安装了客户端驱动和 Python 连接器。可在 Python 交互式 Shell 中输入:import taos对于 WebSocket 连接,只需验证是否能成功导入
taosws模块。可在 Python 交互式 Shell 中输入:import taosws
编辑 go.mod 添加 driver-go 依赖即可。
module goexample
go 1.17
require github.com/taosdata/driver-go/v3 latest
driver-go 使用 cgo 封装了 taosc 的 API。cgo 需要使用 GCC 编译 C 的源码。因此需要确保你的系统上有 GCC。
编辑 Cargo.toml 添加 taos 依赖即可。
[dependencies]
taos = { version = "*"}
Rust 连接器通过不同的特性区分不同的连接方式。默认同时支持原生连接和 WebSocket 连接,如果仅需要建立 WebSocket 连接,可设置 ws 特性:
taos = { version = "*", default-features = false, features = ["ws"] }
-
安装前准备
- 安装 Node.js 开发环境,使用 14 以上版本。下载链接:Download Node.js
-
安装
-
使用 npm 安装 Node.js 连接器
npm install @tdengine/websocketNode.js 目前只支持 WebSocket 连接
-
-
安装验证
-
新建安装验证目录,例如:
~/tdengine-test,下载 GitHub 上 nodejsChecker.js 源代码 到本地。 -
在命令行中执行以下命令。
npm init -y
npm install @tdengine/websocket
node nodejsChecker.js -
执行以上步骤后,在命令行会输出 nodeChecker.js 连接 TDengine TSDB 实例,并执行简单插入和查询的结果。
-
编辑项目配置文件中添加 TDengine TSDB.Connector 的引用即可:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<StartupObject>TDengineExample.AsyncQueryExample</StartupObject>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="TDengine.Connector" Version="3.1.0" />
</ItemGroup>
</Project>
也可通过 dotnet 命令添加:
dotnet add package TDengine.Connector
以下示例代码,均基于 dotnet6.0,如果使用其它版本,可能需要做适当调整。
如果已经安装了 TDengine TSDB 服务端软件或 TDengine TSDB 客户端驱动 taosc,那么已经安装了 C 连接器,无需额外操作。
使用 REST API 方式访问 TDengine TSDB,无需安装任何驱动和连接器。
建立连接
在执行这一步之前,请确保有一个正在运行的,且可以访问到的 TDengine TSDB,而且服务端的 FQDN 配置正确。以下示例代码,都假设 TDengine TSDB 安装在本机,且 FQDN(默认 localhost)和 serverPort(默认 6030)都使用默认配置。
连接参数
连接的配置项较多,因此在建立连接之前,我们能先介绍一下各语言连接器建立连接使用的参数。
- Java
- Python
- Go
- Rust
- Node.js
- C#
- C
- REST API
Java 连接器建立连接的参数有 URL 和 Properties。TDengine TSDB 的 JDBC URL 规范格式为:
jdbc:[TAOS|TAOS-WS]://[host_name]:[port]/[database_name]?[user={user}|&password={password}|&charset={charset}|&cfgdir={config_dir}|&locale={locale}|&timezone={timezone}|&batchfetch={batchfetch}]
URL 和 Properties 的详细参数说明和如何使用详见 url 规范
Python 连接器使用 connect() 方法来建立连接,下面是连接参数的具体说明:
- url:
taosAdapterWebsocket 服务的 URL。默认是localhost的6041端口。 - user:TDengine TSDB 用户名。默认是
root。 - password:TDengine TSDB 用户密码。默认是
taosdata。 - timeout:HTTP 请求超时时间。单位为秒。默认为
socket._GLOBAL_DEFAULT_TIMEOUT。一般无需配置。
URL 的详细参数说明和如何使用详见 url 规范
数据源名称具有通用格式,例如 PEAR DB,但没有类型前缀(方括号表示可选):
[username[:password]@][protocol[(address)]]/[dbname][?param1=value1&...¶mN=valueN]
完整形式的 DSN:
username:password@protocol(address)/dbname?param=value
当使用 IPv6 地址时(v3.7.1 及以上版本支持),地址需要用方括号括起来,例如:
root:taosdata@ws([::1]:6041)/testdb
支持的 DSN 参数如下
-
原生连接:
cfg指定 taos.cfg 目录。cgoThread指定 cgo 同时执行的数量,默认为系统核数。cgoAsyncHandlerPoolSize指定异步函数的 handle 大小,默认为 10000。timezone指定连接使用的时区,sql 解析以及查询结果都会按照此时区进行转换,只支持 IANA 时区格式,特殊字符需要进行编码,以上海时区(Asia/Shanghai)为例:timezone=Asia%2FShanghai。
-
WebSocket 连接:
enableCompression是否发送压缩数据,默认为 false 不发送压缩数据,如果传输数据使用压缩设置为 true。readTimeout读取数据的超时时间,默认为 5m。writeTimeout写入数据的超时时间,默认为 10s。timezone指定连接使用的时区,sql 解析以及查询结果都会按照此时区进行转换,只支持 IANA 时区格式,特殊字符需要进行编码,以上海时区(Asia/Shanghai)为例:timezone=Asia%2FShanghai。
Rust 连接器使用 DSN 来创建连接,DSN 描述字符串基本结构如下:
<driver>[+<protocol>]://[[<username>:<password>@]<host>:<port>][/<database>][?<p1>=<v1>[&<p2>=<v2>]]
|------|------------|---|-----------|-----------|------|------|------------|-----------------------|
|driver| protocol | | username | password | host | port | database | params |
DSN 的详细说明和如何使用详见 连接功能
Node.js 连接器使用 DSN 来创建连接,DSN 描述字符串基本结构如下:
[+<protocol>]://[[<username>:<password>@]<host>:<port>][/<database>][?<p1>=<v1>[&<p2>=<v2>]]
|------------|---|-----------|-----------|------|------|------------|-----------------------|
| protocol | | username | password | host | port | database | params |
-
protocol: 使用 websocket 协议建立连接。例如
ws://localhost:6041 -
username/password: 数据库的用户名和密码。
-
host/port: 参数支持合法的域名或 IP 地址。
@tdengine/websocket同时支持 IPV4 和 IPV6 两种地址格式,对于 IPv6 地址,必须使用中括号括起来(例如[::1]或[2001:db8:1234:5678::1]),以避免端口号解析冲突。 -
database: 数据库名称。
-
params: 其他参数。例如 token。
-
完整 DSN 示例:
// IPV4:
ws://root:taosdata@localhost:6041
// IPV6:
ws://root:taosdata@[::1]:6041
ConnectionStringBuilder 使用 key-value 对方式设置连接参数,key 为参数名,value 为参数值,不同参数之间使用分号 ; 分割。例如:
"protocol=WebSocket;host=127.0.0.1;port=6041;useSSL=false"
-
支持的参数如下:
host:TDengine TSDB 运行实例的地址。port:TDengine TSDB 运行实例的端口。username:连接的用户名。password:连接的密码。protocol:连接的协议,可选值为 Native 或 WebSocket,默认为 Native。db:连接的数据库。timezone:时区,默认为本地时区。connTimeout:连接超时时间,默认为 1 分钟。
-
WebSocket 连接额外支持以下参数:
readTimeout:读取超时时间,默认为 5 分钟。writeTimeout:发送超时时间,默认为 10 秒。token:连接 TDengine TSDB cloud 的 token。useSSL:是否使用 SSL 连接,默认为 false。enableCompression:是否启用 WebSocket 压缩,默认为 false。autoReconnect:是否自动重连,默认为 false。reconnectRetryCount:重连次数,默认为 3。reconnectIntervalMs:重连间隔毫秒时间,默认为 2000。
- C/C++ 连接器使用
taos_connect()函数建立与 TDengine TSDB 数据库的连接。各参数说明如下:host:数据库服务器的主机名或 IP 地址。如果是本地数据库,可以使用"localhost"。user:数据库登录用户名。passwd:对应用户名的登录密码。db:连接时默认使用的数据库名。如果不指定数据库,可以传递NULL或空字符串。port:数据库服务器监听的端口号。原生连接默认端口为6030,WebSocket 连接默认端口为6041。 WebSocket 连接需要先调用taos_options(TSDB_OPTION_DRIVER, "websocket")设置驱动类型,然后再调用taos_connect()建立连接。 原生连接还提供taos_connect_auth()函数,用于使用 MD5 加密的密码建立连接。该函数与taos_connect()功能相同,区别在于密码的处理方式,taos_connect_auth()需要的是密码的 MD5 加密字符串。
通过 REST API 方式访问 TDengine TSDB 时,应用程序直接与 taosAdapter 建立 HTTP 连接,建议使用连接池来管理连接。
使用 REST API 的参数具体可以参考:http-请求格式
WebSocket 连接
下面是各语言连接器建立 WebSocket 连接代码样例。演示了如何使用 WebSocket 连接方式连接到 TDengine TSDB 数据库,并对连接设定一些参数。整个过程主要涉及到数据库连接的建立和异常处理。
- Java
- Python
- Go
- Rust
- Node.js
- C#
- C
public static void main(String[] args) throws Exception {
// use
// String jdbcUrl =
// "jdbc:TAOS-WS://localhost:6041/dbName?user=root&password=taosdata";
// if you want to connect a specified database named "dbName".
String jdbcUrl = "jdbc:TAOS-WS://localhost:6041?user=root&password=taosdata";
Properties connProps = new Properties();
connProps.setProperty(TSDBDriver.PROPERTY_KEY_ENABLE_AUTO_RECONNECT, "true");
connProps.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
connProps.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
try (Connection conn = DriverManager.getConnection(jdbcUrl, connProps)) {
System.out.println("Connected to " + jdbcUrl + " successfully.");
// you can use the connection for execute SQL here
} catch (Exception ex) {
// please refer to the JDBC specifications for detailed exceptions info
System.out.printf("Failed to connect to %s, %sErrMessage: %s%n",
jdbcUrl,
ex instanceof SQLException ? "ErrCode: " + ((SQLException) ex).getErrorCode() + ", " : "",
ex.getMessage());
// Print stack trace for context in examples. Use logging in production.
ex.printStackTrace();
throw ex;
}
}
import taosws
def create_connection():
conn = None
host = "localhost"
port = 6041
try:
conn = taosws.connect(
user="root",
password="taosdata",
host=host,
port=port,
)
print(f"Connected to {host}:{port} successfully.");
except Exception as err:
print(f"Failed to connect to {host}:{port} , ErrMessage:{err}")
raise err
return conn
查看源码
SQLAlchemy 支持通过 hosts 参数配置多个服务器地址,实现负载均衡和故障转移功能。多个地址使用英文逗号分隔,格式为:hosts=<host1>:<port1>,<host2>:<port2>,...
import warnings
from sqlalchemy.exc import SAWarning
# Suppress specific SQLAlchemy warnings
warnings.filterwarnings(
"ignore",
category=SAWarning,
message="Dialect taosws:taosws will not make use of SQL compilation caching"
)
import taosws
from sqlalchemy import create_engine
from sqlalchemy import text
def create_connection_with_sqlalchemy():
engine = create_engine(url="taosws://root:taosdata@?hosts=localhost:6041,127.0.0.1:6041&timezone=Asia/Shanghai")
conn = engine.connect()
return conn
package main
import (
"database/sql"
"fmt"
"log"
_ "github.com/taosdata/driver-go/v3/taosWS"
)
func main() {
// use
// var taosDSN = "root:taosdata@ws(localhost:6041)/dbName"
// if you want to connect a specified database named "dbName".
var taosDSN = "root:taosdata@ws(localhost:6041)/"
taos, err := sql.Open("taosWS", taosDSN)
if err != nil {
log.Fatalln("Failed to connect to " + taosDSN + "; ErrMessage: " + err.Error())
}
fmt.Println("Connected to " + taosDSN + " successfully.")
defer taos.Close()
}
use taos::*;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let dsn = "ws://localhost:6041";
match TaosBuilder::from_dsn(dsn)?.build().await {
Ok(_taos) => {
println!("Connected to {} successfully.", dsn);
Ok(())
}
Err(err) => {
eprintln!("Failed to connect to {}, ErrMessage: {}", dsn, err);
return Err(err.into());
}
}
}
const taos = require("@tdengine/websocket");
let dsn = 'ws://localhost:6041';
async function createConnect() {
try {
let conf = new taos.WSConfig(dsn);
conf.setUser('root');
conf.setPwd('taosdata');
conf.setDb('power');
conn = await taos.sqlConnect(conf);
console.log("Connected to " + dsn + " successfully.");
return conn;
} catch (err) {
console.log("Failed to connect to " + dsn + ", ErrCode: " + err.code + ", ErrMessage: " + err.message);
throw err;
}
}
static void Main(string[] args)
{
var connectionString =
"protocol=WebSocket;host=localhost;port=6041;useSSL=false;username=root;password=taosdata";
try
{
// Connect to TDengine server using WebSocket
var builder = new ConnectionStringBuilder(connectionString);
// Open connection with using block, it will close the connection automatically
using (var client = DbDriver.Open(builder))
{
Console.WriteLine("Connected to " + connectionString + " successfully.");
}
}
catch (TDengineError e)
{
// handle TDengine error
Console.WriteLine("Failed to connect to " + connectionString + "; ErrCode:" + e.Code +
"; ErrMessage: " + e.Error);
throw;
}
catch (Exception e)
{
// handle other exceptions
Console.WriteLine("Failed to connect to " + connectionString + "; Err:" + e.Message);
throw;
}
}
// to compile: gcc -o connect_example connect_example.c -ltaos
#include <stdio.h>
#include <stdlib.h>
#include "taos.h"
int main() {
const char *host = "localhost";
const char *user = "root";
const char *passwd = "taosdata";
const char *db = NULL;
uint16_t port = 6041;
int code = taos_options(TSDB_OPTION_DRIVER, "websocket");
if (code != 0) {
fprintf(stderr, "Failed to set driver option, code: %d\n", code);
return -1;
}
TAOS *taos = taos_connect(host, user, passwd, db, port);
fprintf(stdout, "Connected to %s:%hu successfully.\n", host, port);
/* put your code here for read and write */
taos_close(taos);
taos_cleanup();
}
原生连接
下面是各语言连接器建立原生连接代码样例。演示了如何使用原生连接方式连接到 TDengine TSDB 数据库,并对连接设定一些参数。整个过程主要涉及到数据库连接的建立和异常处理。
- Java
- Python
- Go
- Rust
- Node.js
- C#
- C
public static void main(String[] args) throws Exception {
// use
// String jdbcUrl =
// "jdbc:TAOS://localhost:6030/dbName?user=root&password=taosdata";
// if you want to connect a specified database named "dbName".
String jdbcUrl = "jdbc:TAOS://localhost:6030?user=root&password=taosdata";
Properties connProps = new Properties();
connProps.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
connProps.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
connProps.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
try (Connection conn = DriverManager.getConnection(jdbcUrl, connProps)) {
System.out.println("Connected to " + jdbcUrl + " successfully.");
// you can use the connection for execute SQL here
} catch (Exception ex) {
// please refer to the JDBC specifications for detailed exceptions info
System.out.printf("Failed to connect to %s, %sErrMessage: %s%n",
jdbcUrl,
ex instanceof SQLException ? "ErrCode: " + ((SQLException) ex).getErrorCode() + ", " : "",
ex.getMessage());
// Print stack trace for context in examples. Use logging in production.
ex.printStackTrace();
throw ex;
}
}
import taos
def create_connection():
# all parameters are optional.
conn = None
host = "localhost"
port = 6030
try:
conn = taos.connect(
user="root",
password="taosdata",
host=host,
port=port,
)
print(f"Connected to {host}:{port} successfully.");
except Exception as err:
print(f"Failed to connect to {host}:{port} , ErrMessage:{err}")
raise err
finally:
if conn:
conn.close()
if __name__ == "__main__":
create_connection()
package main
import (
"database/sql"
"fmt"
"log"
_ "github.com/taosdata/driver-go/v3/taosSql"
)
func main() {
// use
// var taosDSN = "root:taosdata@tcp(localhost:6030)/dbName"
// if you want to connect a specified database named "dbName".
var taosDSN = "root:taosdata@tcp(localhost:6030)/"
taos, err := sql.Open("taosSql", taosDSN)
if err != nil {
log.Fatalln("Failed to connect to " + taosDSN + "; ErrMessage: " + err.Error())
}
fmt.Println("Connected to " + taosDSN + " successfully.")
defer taos.Close()
}
use taos::*;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let dsn = "taos://localhost:6030";
match TaosBuilder::from_dsn(dsn)?.build().await {
Ok(_taos) => {
println!("Connected to {} successfully.", dsn);
Ok(())
}
Err(err) => {
eprintln!("Failed to connect to {}, ErrMessage: {}", dsn, err);
return Err(err.into());
}
}
}
不支持
static void Main(String[] args)
{
var connectionString = "host=127.0.0.1;port=6030;username=root;password=taosdata";
try
{
// Connect to TDengine server using Native
var builder = new ConnectionStringBuilder(connectionString);
// Open connection with using block, it will close the connection automatically
using (var client = DbDriver.Open(builder))
{
Console.WriteLine("Connected to " + connectionString + " successfully.");
}
}
catch (TDengineError e)
{
// handle TDengine error
Console.WriteLine("Failed to connect to " + connectionString + "; ErrCode:" + e.Code + "; ErrMessage: " + e.Error);
throw;
}
catch (Exception e)
{
// handle other exceptions
Console.WriteLine("Failed to connect to " + connectionString + "; Err:" + e.Message);
throw;
}
}
// compile with
// gcc connect_example.c -o connect_example -ltaos
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <taos.h>
#include <unistd.h> // for sleep()
int main() {
int32_t code = 0;
const char *host = "localhost";
const char *user = "root";
const char *passwd = "taosdata";
const char *db = NULL; // if don't want to connect to a default db, set it to NULL or ""
uint16_t port = 6030; // 0 means use the default port
TAOS *taos = taos_connect(host, user, passwd, db, port);
if (taos == NULL) {
fprintf(stderr, "Failed to connect to %s:%hu, ErrCode: 0x%x, ErrMessage: %s.\n", host, port, taos_errno(NULL),
taos_errstr(NULL));
taos_cleanup();
return -1;
}
code = taos_options_connection(taos, TSDB_OPTION_CONNECTION_USER_IP, "192.168.1.1");
if (code != 0) {
fprintf(stderr, "Failed to set user ip, ErrCode: 0x%x, ErrMessage: %s.\n", taos_errno(taos), taos_errstr(taos));
taos_close(taos);
taos_cleanup();
return -1;
}
sleep(5);
{
TAOS_RES *res = taos_query(taos, "show connections");
if (taos == NULL) {
fprintf(stderr, "Failed to connect to %s:%hu, ErrCode: 0x%x, ErrMessage: %s.\n", host, port, taos_errno(NULL),
taos_errstr(NULL));
taos_cleanup();
return -1;
}
taos_free_result(res);
}
fprintf(stdout, "Connected to %s:%hu successfully.\n", host, port);
/* put your code here for read and write */
// close & clean
taos_close(taos);
taos_cleanup();
}
如果建立连接失败,大部分情况下是 FQDN 或防火墙的配置不正确,详细的排查方法请看《常见问题及反馈》中的“遇到错误 Unable to establish connection, 我怎么办?”
连接池
有些连接器提供了连接池,或者可以与已有的连接池组件配合使用。使用连接池,应用程序可以快速地从连接池中获取可用连接,避免了每次操作时创建和销毁连接的开销。这不仅减少了资源消耗,还提高了响应速度。此外,连接池还支持对连接的管理,如最大连接数限制、连接的有效性检查,确保了连接的高效和可靠使用。我们推荐使用连接池管理连接。
下面是各语言连接器的连接池支持代码样例。
- Java
- Python
- Go
- Rust
HikariCP
使用示例如下:
public static void main(String[] args) throws Exception {
HikariConfig config = new HikariConfig();
// jdbc properties
config.setJdbcUrl("jdbc:TAOS-WS://127.0.0.1:6041/log");
config.setUsername("root");
config.setPassword("taosdata");
// connection pool configurations
config.setMinimumIdle(10); // minimum number of idle connection
config.setMaximumPoolSize(10); // maximum number of connection in the pool
config.setConnectionTimeout(30000); // maximum wait milliseconds for get connection from pool
config.setMaxLifetime(0); // maximum life time for each connection
config.setIdleTimeout(0); // max idle time for recycle idle connection
HikariDataSource dataSource = new HikariDataSource(config); // create datasource
Connection connection = dataSource.getConnection(); // get connection
Statement statement = connection.createStatement(); // get statement
// query or insert
// ...
statement.close();
connection.close(); // put back to connection pool
dataSource.close();
}
通过 HikariDataSource.getConnection() 获取连接后,使用完成后需要调用 close() 方法,实际上它并不会关闭连接,只是放回连接池中。 更多 HikariCP 使用问题请查看官方说明。
Druid
使用示例如下:
public static void main(String[] args) throws Exception {
String url = "jdbc:TAOS-WS://127.0.0.1:6041/log";
DruidDataSource dataSource = new DruidDataSource();
// jdbc properties
dataSource.setDriverClassName("com.taosdata.jdbc.ws.WebSocketDriver");
dataSource.setUrl(url);
dataSource.setUsername("root");
dataSource.setPassword("taosdata");
// pool configurations
dataSource.setInitialSize(10);
dataSource.setMinIdle(10);
dataSource.setMaxActive(10);
dataSource.setMaxWait(30000);
Connection connection = dataSource.getConnection(); // get connection
Statement statement = connection.createStatement(); // get statement
// query or insert
// ...
statement.close();
connection.close(); // put back to connection pool
dataSource.close();
}
更多 druid 使用问题请查看官方说明。
SQLAlchemy 连接池示例(推荐使用)
import taosws
from sqlalchemy import create_engine
from sqlalchemy import text
import threading
# Create a SQLAlchemy engine with WebSocket connection
# If using native connection, use `taos` instead of `taosws`
engine = create_engine(url="taosws://root:taosdata@?hosts=localhost:6041,127.0.0.1:6041&timezone=Asia/Shanghai", pool_size=10, max_overflow=20)
def init_db():
try:
with engine.begin() as conn:
# create database
conn.execute(text("DROP DATABASE IF EXISTS power"))
conn.execute(text("CREATE DATABASE IF NOT EXISTS power"))
print(f"Create database power successfully")
# create super table
conn.execute(
text("CREATE TABLE IF NOT EXISTS power.meters (`ts` TIMESTAMP, `current` FLOAT, `voltage` INT, `phase` FLOAT) TAGS (`groupid` INT, `location` BINARY(64))")
)
print(f"Create stable power.meters successfully")
except Exception as err:
print(f"Failed to create db and table; ErrMessage:{err}")
raise
def ws_insert_sql(i: int):
try:
with engine.begin() as conn:
sql = text(f"""
INSERT INTO
power.d1001 USING power.meters (groupid, location) TAGS(2, 'California.SanFrancisco')
VALUES (NOW + {i+1}a, 10.30000, 219, 0.31000)
(NOW + {i+2}a, 12.60000, 218, 0.33000) (NOW + {i+3}a, 12.30000, 221, 0.31000)
power.d1002 USING power.meters (groupid, location) TAGS(3, 'California.SanFrancisco')
VALUES (NOW + {i+1}a, 10.30000, 218, 0.25000)
""")
affectedRows = conn.execute(sql)
print(f"Successfully inserted {affectedRows.cursor.row_count} rows to power.meters.")
except Exception as err:
print(f"Failed to insert data to power.meters; ErrMessage:{err}")
raise
# Use connection pool to execute queries
def ws_query(sql: str):
try:
# Get connection from pool
with engine.begin() as conn:
# Execute SQL
result = conn.execute(text(sql))
# Get results
data = result.fetchall()
print(f"Query result: {data}")
return data
except Exception as e:
print(f"TDengine query failed: {e}")
raise
if __name__ == "__main__":
init_db() # Initialize database and tables
threads = []
for i in range(5):
t1 = threading.Thread(target=ws_insert_sql, args=(i*10,))
t2 = threading.Thread(target=ws_query, args=("SELECT * FROM power.meters",))
threads.extend([t1, t2])
t1.start()
t2.start()
for t in threads:
t.join()
data = ws_query("SELECT count(*) FROM power.meters")
assert data[0][0] == 20, "Expected 20 rows in power.meters"
print("All sub-threads completed, main thread ending")
DBUtils 连接池示例
import threading
from dbutils.pooled_db import PooledDB
import taosws
def init_websocket_pool():
return PooledDB(
# Set connector driver. If using native mode, please replace taosws with taos
creator=taosws,
# Maximum number of connections
maxconnections=10,
# TDengine connection parameters (modify according to actual environment)
host="localhost",
port=6041,
user="root",
password="taosdata",
charset="UTF-8"
)
websocket_pool = init_websocket_pool()
def init_db():
try:
conn = websocket_pool.connection()
cursor = conn.cursor()
# create database
cursor.execute(f"Drop DATABASE IF EXISTS power")
rowsAffected = cursor.execute(f"CREATE DATABASE IF NOT EXISTS power")
print(f"Create database power successfully, rowsAffected: {rowsAffected}")
assert rowsAffected == 0
# create super table
rowsAffected = cursor.execute(
"CREATE TABLE IF NOT EXISTS power.meters (`ts` TIMESTAMP, `current` FLOAT, `voltage` INT, `phase` FLOAT) TAGS (`groupid` INT, `location` BINARY(64))"
)
print(f"Create stable power.meters successfully, rowsAffected: {rowsAffected}");
except Exception as err:
print(f"Failed to create db and table; ErrMessage:{err}")
finally:
if conn:
conn.close()
def ws_insert_sql(i: int):
conn = None
try:
conn = websocket_pool.connection()
cursor = conn.cursor()
sql = f"""
INSERT INTO
power.d1001 USING power.meters (groupid, location) TAGS(2, 'California.SanFrancisco')
VALUES (NOW + {i+1}a, 10.30000, 219, 0.31000)
(NOW + {i+2}a, 12.60000, 218, 0.33000) (NOW + {i+3}a, 12.30000, 221, 0.31000)
power.d1002 USING power.meters (groupid, location) TAGS(3, 'California.SanFrancisco')
VALUES (NOW + {i+1}a, 10.30000, 218, 0.25000)
"""
affectedRows = cursor.execute(sql)
print(f"Successfully inserted {affectedRows} rows to power.meters.")
except Exception as err:
print(f"Failed to insert data to power.meters; ErrMessage:{err}")
finally:
if conn:
conn.close()
# Execute queries using connection pool
def ws_query(sql: str):
conn = None
cursor = None
try:
# Get connection from pool
conn = websocket_pool.connection()
# Create cursor
cursor = conn.cursor()
# Execute SQL
cursor.execute(sql)
# Get results
data = cursor.fetchall()
print(data)
return data
except Exception as e:
print(f"TDengine query failed: {e}")
raise
finally:
# Close cursor
if cursor:
cursor.close()
# Return connection to pool (not actually closed, just marked as idle)
if conn:
conn.close()
if __name__ == "__main__":
init_db() # Initialize database and tables
threads = []
for i in range(5):
t1 = threading.Thread(target=ws_insert_sql, args=(i*10,))
t2 = threading.Thread(target=ws_query, args=("SELECT * FROM power.meters",))
threads.extend([t1, t2])
t1.start()
t2.start()
for t in threads:
t.join()
data = ws_query("SELECT count(*) FROM power.meters")
assert data[0][0] == 20, "Expected 20 rows in power.meters"
print("All sub-threads completed, main thread ending")
使用 sql.Open 创建出来的连接已经实现了连接池,可以通过 API 设置连接池参数,样例如下
// SetMaxOpenConns sets the maximum number of open connections to the database. 0 means unlimited.
taos.SetMaxOpenConns(0)
// SetMaxIdleConns sets the maximum number of connections in the idle connection pool.
taos.SetMaxIdleConns(2)
// SetConnMaxLifetime sets the maximum amount of time a connection may be reused.
taos.SetConnMaxLifetime(0)
// SetConnMaxIdleTime sets the maximum amount of time a connection may be idle.
taos.SetConnMaxIdleTime(0)
在复杂应用中,建议启用连接池。taos 的连接池在异步模式下使用 deadpool 实现。
创建默认参数的连接池:
let pool: Pool<TaosBuilder> = TaosBuilder::from_dsn("taos:///")
.unwrap()
.pool()
.unwrap();
使用连接池构造器自定义参数:
let pool: Pool<TaosBuilder> = Pool::builder(Manager::from_dsn("taos:///").unwrap().0)
.max_size(88) // 最大连接数
.build()
.unwrap();
从连接池获取连接对象:
let taos = pool.get().await?;







