Merge remote-tracking branch 'origin/3.0' into enh/TD-21826-3.0
|
@ -27,7 +27,7 @@ docker pull tdengine/tdengine:3.0.1.4
|
|||
And then run the following command:
|
||||
|
||||
```shell
|
||||
docker run -d -p 6030:6030 -p 6041:6041 -p 6043-6049:6043-6049 -p 6043-6049:6043-6049/udp tdengine/tdengine
|
||||
docker run -d -p 6030:6030 -p 6041:6041 -p 6043-6060:6043-6060 -p 6043-6060:6043-6060/udp tdengine/tdengine
|
||||
```
|
||||
|
||||
Note that TDengine Server 3.0 uses TCP port 6030. Port 6041 is used by taosAdapter for the REST API service. Ports 6043 through 6049 are used by taosAdapter for other connections. You can open these ports as needed.
|
||||
|
@ -36,7 +36,7 @@ If you need to persist data to a specific directory on your local machine, pleas
|
|||
```shell
|
||||
docker run -d -v ~/data/taos/dnode/data:/var/lib/taos \
|
||||
-v ~/data/taos/dnode/log:/var/log/taos \
|
||||
-p 6030:6030 -p 6041:6041 -p 6043-6049:6043-6049 -p 6043-6049:6043-6049/udp tdengine/tdengine
|
||||
-p 6030:6030 -p 6041:6041 -p 6043-6060:6043-6060 -p 6043-6060:6043-6060/udp tdengine/tdengine
|
||||
```
|
||||
:::note
|
||||
|
||||
|
@ -62,7 +62,7 @@ You can now access TDengine or run other Linux commands.
|
|||
|
||||
Note: For information about installing docker, see the [official documentation](https://docs.docker.com/get-docker/).
|
||||
|
||||
## Open the TDengine CLI
|
||||
## TDengine Command Line Interface
|
||||
|
||||
On the container, run the following command to open the TDengine CLI:
|
||||
|
||||
|
@ -73,6 +73,12 @@ taos>
|
|||
|
||||
```
|
||||
|
||||
## TDegnine Graphic User Interface
|
||||
|
||||
From TDengine 3.3.0.0, there is a new componenet called `taos-explorer` added in the TDengine docker image. You can use it to manage the databases, super tables, child tables, and data in your TDengine system. There are also some features only available in TDengine Enterprise Edition, please contact TDengine sales team in case you need these features.
|
||||
|
||||
To use taos-explorer in the container, you need to access the host port mapped from container port 6060. Assuming the host name is abc.com, and the port used on host is 6060, you need to access `http://abc.com:6060`. taos-explorer uses port 6060 by default in the container. When you use it the first time, you need to register with your enterprise email, then can logon using your user name and password in the TDengine database management system.
|
||||
|
||||
## Test data insert performance
|
||||
|
||||
After your TDengine Server is running normally, you can run the taosBenchmark utility to test its performance:
|
||||
|
@ -125,6 +131,7 @@ SELECT FIRST(ts), AVG(current), MAX(voltage), MIN(phase) FROM test.d10 INTERVAL(
|
|||
|
||||
In the query above you are selecting the first timestamp (ts) in the interval, another way of selecting this would be `\_wstart` which will give the start of the time window. For more information about windowed queries, see [Time-Series Extensions](../../taos-sql/distinguished/).
|
||||
|
||||
|
||||
## Additional Information
|
||||
|
||||
For more information about deploying TDengine in a Docker environment, see [Deploying TDengine with Docker](../../deployment/docker).
|
||||
|
|
|
@ -35,6 +35,10 @@ gcc version - 9.3.1 or above;
|
|||
|
||||
## Installation
|
||||
|
||||
**Note**
|
||||
|
||||
Since TDengine 3.0.6.0, we don't provide standalone taosTools pacakge for downloading. However, all the tools included in the taosTools pacakge can be found in TDengine-server pacakge.
|
||||
|
||||
<Tabs>
|
||||
<TabItem label=".deb" value="debinst">
|
||||
|
||||
|
@ -119,11 +123,18 @@ This installation method is supported only for Debian and Ubuntu.
|
|||
</TabItem>
|
||||
<TabItem label="Windows" value="windows">
|
||||
|
||||
Note: TDengine only supports Windows Server 2016/2019 and Windows 10/11 on the Windows platform.
|
||||
**Note**
|
||||
- TDengine only supports Windows Server 2016/2019 and Windows 10/11 on the Windows platform.
|
||||
- Since TDengine 3.1.0.0, we wonly provide client package for Windows. If you need to run TDenginer server on Windows, please contact TDengine sales team to upgrade to TDengine Enterprise.
|
||||
- To run on Windows, the Microsoft Visual C++ Runtime library is required. If the Microsoft Visual C++ Runtime Library is missing on your platform, you can download and install it from [VC Runtime Library](https://learn.microsoft.com/en-us/cpp/windows/latest-supported-vc-redist?view=msvc-170).
|
||||
|
||||
Follow the steps below:
|
||||
|
||||
1. Download the Windows installation package.
|
||||
<PkgListV3 type={3}/>
|
||||
2. Run the downloaded package to install TDengine.
|
||||
Note: From version 3.0.1.7, only TDengine client pacakge can be downloaded for Windows platform. If you want to run TDengine servers on Windows, please contact our sales team to upgrade to TDengine Enterprise.
|
||||
|
||||
|
||||
</TabItem>
|
||||
<TabItem label="macOS" value="macos">
|
||||
|
@ -153,38 +164,26 @@ After the installation is complete, run the following command to start the TDeng
|
|||
|
||||
```bash
|
||||
systemctl start taosd
|
||||
systemctl start taosadapter
|
||||
systemctl start taoskeeper
|
||||
systemctl start taos-explorer
|
||||
```
|
||||
|
||||
Run the following command to confirm that TDengine is running normally:
|
||||
Or you can run a scrip to start all the above services together
|
||||
|
||||
```bash
|
||||
start-all.sh
|
||||
```
|
||||
|
||||
systemctl can also be used to stop, restart a specific service or check its status, like below using `taosd` as example:
|
||||
|
||||
```bash
|
||||
systemctl start taosd
|
||||
systemctl stop taosd
|
||||
systemctl restart taosd
|
||||
systemctl status taosd
|
||||
```
|
||||
|
||||
Output similar to the following indicates that TDengine is running normally:
|
||||
|
||||
```
|
||||
Active: active (running)
|
||||
```
|
||||
|
||||
Output similar to the following indicates that TDengine has not started successfully:
|
||||
|
||||
```
|
||||
Active: inactive (dead)
|
||||
```
|
||||
|
||||
After confirming that TDengine is running, run the `taos` command to access the TDengine CLI.
|
||||
|
||||
The following `systemctl` commands can help you manage TDengine service:
|
||||
|
||||
- Start TDengine Server: `systemctl start taosd`
|
||||
|
||||
- Stop TDengine Server: `systemctl stop taosd`
|
||||
|
||||
- Restart TDengine Server: `systemctl restart taosd`
|
||||
|
||||
- Check TDengine Server status: `systemctl status taosd`
|
||||
|
||||
:::info
|
||||
|
||||
- The `systemctl` command requires _root_ privileges. If you are not logged in as the _root_ user, use the `sudo` command.
|
||||
|
@ -193,35 +192,38 @@ The following `systemctl` commands can help you manage TDengine service:
|
|||
|
||||
:::
|
||||
|
||||
## Command Line Interface (CLI)
|
||||
|
||||
You can use the TDengine CLI to monitor your TDengine deployment and execute ad hoc queries. To open the CLI, you can execute `taos` in terminal.
|
||||
|
||||
</TabItem>
|
||||
|
||||
<TabItem label="Windows" value="windows">
|
||||
|
||||
After the installation is complete, please run `sc start taosd` or run `C:\TDengine\taosd.exe` with administrator privilege to start TDengine Server. Please run `sc start taosadapter` or run `C:\TDengine\taosadapter.exe` with administrator privilege to start taosAdapter to provide http/REST service.
|
||||
|
||||
## Command Line Interface (CLI)
|
||||
|
||||
You can use the TDengine CLI to monitor your TDengine deployment and execute ad hoc queries. To open the CLI, you can run `taos.exe` in the `C:\TDengine` directory of the Windows terminal to start the TDengine command line.
|
||||
|
||||
</TabItem>
|
||||
|
||||
<TabItem label="macOS" value="macos">
|
||||
|
||||
After the installation is complete, double-click the /applications/TDengine to start the program, or run `launchctl start com.tdengine.taosd` to start TDengine Server.
|
||||
After the installation is complete, double-click the /applications/TDengine to start the program, or run `sudo launchctl start ` to start TDengine services.
|
||||
|
||||
The following `launchctl` commands can help you manage TDengine service:
|
||||
```bash
|
||||
sudo launchctl start com.tdengine.taosd
|
||||
sudo launchctl start com.tdengine.taosadapter
|
||||
sudo launchctl start com.tdengine.taoskeeper
|
||||
sudo launchctl start com.tdengine.taos-explorer
|
||||
```
|
||||
|
||||
- Start TDengine Server: `sudo launchctl start com.tdengine.taosd`
|
||||
Or you can run a scrip to start all the above services together
|
||||
```bash
|
||||
start-all.sh
|
||||
```
|
||||
|
||||
- Stop TDengine Server: `sudo launchctl stop com.tdengine.taosd`
|
||||
The following `launchctl` commands can help you manage TDengine service, using `taosd` service as an example below:
|
||||
|
||||
- Check TDengine Server status: `sudo launchctl list | grep taosd`
|
||||
|
||||
- Check TDengine Server status details: `launchctl print system/com.tdengine.taosd`
|
||||
```bash
|
||||
sudo launchctl start com.tdengine.taosd
|
||||
sudo launchctl stop com.tdengine.taosd
|
||||
sudo launchctl list | grep taosd
|
||||
sudo launchctl print system/com.tdengine.taosd
|
||||
```
|
||||
|
||||
:::info
|
||||
- Please use `sudo` to run `launchctl` to manage _com.tdengine.taosd_ with administrator privileges.
|
||||
|
@ -232,24 +234,20 @@ The following `launchctl` commands can help you manage TDengine service:
|
|||
|
||||
:::
|
||||
|
||||
## Command Line Interface (CLI)
|
||||
|
||||
You can use the TDengine CLI to monitor your TDengine deployment and execute ad hoc queries. To open the CLI, you can execute `taos` in terminal.
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
```bash
|
||||
taos
|
||||
```
|
||||
|
||||
The TDengine CLI displays a welcome message and version information to indicate that its connection to the TDengine service was successful. If an error message is displayed, see the [FAQ](../../train-faq/faq) for troubleshooting information. At the following prompt, you can execute SQL commands.
|
||||
## TDengine Command Line Interface
|
||||
|
||||
You can use the TDengine CLI to monitor your TDengine deployment and execute ad hoc queries. To open the CLI, you can execute `taos` (Linux/Mac) or `taos.exe` (Windows) in terminal. The prompt of TDengine CLI is like below:
|
||||
|
||||
```cmd
|
||||
taos>
|
||||
```
|
||||
|
||||
For example, you can create and delete databases and tables and run all types of queries. Each SQL command must be end with a semicolon (;). For example:
|
||||
Using TDengine CLI, you can create and delete databases and tables and run all types of queries. Each SQL command must be end with a semicolon (;). For example:
|
||||
|
||||
```sql
|
||||
CREATE DATABASE demo;
|
||||
|
@ -269,6 +267,12 @@ Query OK, 2 row(s) in set (0.003128s)
|
|||
|
||||
You can also can monitor the deployment status, add and remove user accounts, and manage running instances. You can run the TDengine CLI on either machines. For more information, see [TDengine CLI](../../reference/taos-shell/).
|
||||
|
||||
## TDengine Graphic User Interface
|
||||
|
||||
From TDengine 3.3.0.0, there is a new componenet called `taos-explorer` added in the TDengine docker image. You can use it to manage the databases, super tables, child tables, and data in your TDengine system. There are also some features only available in TDengine Enterprise Edition, please contact TDengine sales team in case you need these features.
|
||||
|
||||
To use taos-explorer in the container, you need to access the host port mapped from container port 6060. Assuming the host name is abc.com, and the port used on host is 6060, you need to access `http://abc.com:6060`. taos-explorer uses port 6060 by default in the container. When you use it the first time, you need to register with your enterprise email, then can logon using your user name and password in the TDengine
|
||||
|
||||
## Test data insert performance
|
||||
|
||||
After your TDengine Server is running normally, you can run the taosBenchmark utility to test its performance:
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
```rust title="Native Connection/REST Connection"
|
||||
```rust title="Native Connection"
|
||||
{{#include docs/examples/rust/nativeexample/examples/connect.rs}}
|
||||
```
|
||||
|
||||
:::note
|
||||
For Rust client library, the connection depends on the feature being used. If "rest" feature is enabled, then only the implementation for "rest" is compiled and packaged.
|
||||
For Rust client library, the connection depends on the feature being used. If "ws" feature is enabled, then only the implementation for "websocket" is compiled and packaged.
|
||||
|
||||
:::
|
||||
|
|
After Width: | Height: | Size: 14 KiB |
|
@ -26,17 +26,24 @@ Any application running on any platform can access TDengine through the REST API
|
|||
|
||||
## Establish Connection
|
||||
|
||||
There are two ways for a client library to establish connections to TDengine:
|
||||
There are three ways for a client library to establish connections to TDengine:
|
||||
|
||||
1. REST connection through the REST API provided by the taosAdapter component.
|
||||
2. Native connection through the TDengine client driver (taosc).
|
||||
1. Native connection through the TDengine client driver (taosc).
|
||||
2. REST connection through the REST API provided by the taosAdapter component.
|
||||
3. Websocket connection provided by the taosAdapter component.
|
||||
|
||||
For REST and native connections, client libraries provide similar APIs for performing operations and running SQL statements on your databases. The main difference is the method of establishing the connection, which is not visible to users.
|
||||

|
||||
|
||||
For these ways of connections, client libraries provide similar APIs for performing operations and running SQL statements on your databases. The main difference is the method of establishing the connection, which is not visible to users.
|
||||
|
||||
Key differences:
|
||||
|
||||
3. The REST connection is more accessible with cross-platform support, however it results in a 30% performance downgrade.
|
||||
1. The TDengine client driver (taosc) has the highest performance with all the features of TDengine like [Parameter Binding](../../client-libraries/cpp#parameter-binding-api), [Subscription](../../client-libraries/cpp#subscription-api), etc.
|
||||
1. For a Native connection, the client driver taosc and the server TDengine version must be compatible.
|
||||
2. For a REST connection, users do not need to install the client driver taosc, providing the advantage of cross-platform ease of use. However, functions such as data subscription and binary data types are not available. Additionally, compared to Native and Websocket connections, a REST connection has the worst performance.
|
||||
3. For a Websocket connection, users also do not need to install the client driver taosc.
|
||||
4. To connect to a cloud service instance, you need to use the REST connection or Websocket connection.
|
||||
|
||||
Normally we recommend using **Websocket connection**.
|
||||
|
||||
## Install Client Driver taosc
|
||||
|
||||
|
@ -123,18 +130,18 @@ require github.com/taosdata/driver-go/v3 latest
|
|||
</TabItem>
|
||||
<TabItem label="Rust" value="rust">
|
||||
|
||||
Just need to add `libtaos` dependency in `Cargo.toml`.
|
||||
Just need to add `taos` dependency in `Cargo.toml`.
|
||||
|
||||
```toml title=Cargo.toml
|
||||
[dependencies]
|
||||
libtaos = { version = "0.4.2"}
|
||||
taos = { version = "*"}
|
||||
```
|
||||
|
||||
:::info
|
||||
Rust client library uses different features to distinguish the way to establish connection. To establish REST connection, please enable `rest` feature.
|
||||
Rust client library uses different features to distinguish the way to establish connection. To establish Websocket connection, please enable `ws` feature.
|
||||
|
||||
```toml
|
||||
libtaos = { version = "*", features = ["rest"] }
|
||||
taos = { version = "*", default-features = false, features = ["ws"] }
|
||||
```
|
||||
|
||||
:::
|
||||
|
|
|
@ -13,14 +13,23 @@ import GoInfluxLine from "../07-develop/03-insert-data/_go_line.mdx"
|
|||
import GoOpenTSDBTelnet from "../07-develop/03-insert-data/_go_opts_telnet.mdx"
|
||||
import GoOpenTSDBJson from "../07-develop/03-insert-data/_go_opts_json.mdx"
|
||||
import GoQuery from "../07-develop/04-query-data/_go.mdx"
|
||||
import RequestId from "./_request_id.mdx";
|
||||
|
||||
`driver-go` is the official Go language client library for TDengine. It implements the [database/sql](https://golang.org/pkg/database/sql/) package, the generic Go language interface to SQL databases. Go developers can use it to develop applications that access TDengine cluster data.
|
||||
|
||||
`driver-go` provides two ways to establish connections. One is **native connection**, which connects to TDengine instances natively through the TDengine client driver (taosc), supporting data writing, querying, subscriptions, schemaless writing, and bind interface. The other is the **REST connection**, which connects to TDengine instances via the REST interface provided by taosAdapter. The set of features implemented by the REST connection differs slightly from those implemented by the native connection.
|
||||
## Connection types
|
||||
|
||||
This article describes how to install `driver-go` and connect to TDengine clusters and perform basic operations such as data query and data writing through `driver-go`.
|
||||
`driver-go` provides 3 connection types.
|
||||
|
||||
The source code of `driver-go` is hosted on [GitHub](https://github.com/taosdata/driver-go).
|
||||
* **Native connection**, which connects to TDengine instances natively through the TDengine client driver (taosc), supporting data writing, querying, subscriptions, schemaless writing, and bind interface.
|
||||
* **REST connection**, which is implemented through taosAdapter. Some features like schemaless and subscriptions are not supported.
|
||||
* **Websocket connection** which is implemented through taosAdapter. The set of features implemented by the WebSocket connection differs slightly from those implemented by the native connection.
|
||||
|
||||
For a detailed introduction of the connection types, please refer to: [Establish Connection](../../develop/connect/#establish-connection)
|
||||
|
||||
## Compatibility
|
||||
|
||||
Supports minimum Go version 1.14, it is recommended to use the latest Go version
|
||||
|
||||
## Supported platforms
|
||||
|
||||
|
@ -233,45 +242,27 @@ The Go client library does not support this feature
|
|||
### Create database and tables
|
||||
|
||||
```go
|
||||
var taosDSN = "root:taosdata@tcp(localhost:6030)/"
|
||||
taos, err := sql.Open("taosSql", taosDSN)
|
||||
if err != nil {
|
||||
log.Fatalln("failed to connect TDengine, err:", err)
|
||||
}
|
||||
defer taos.Close()
|
||||
_, err := taos.Exec("CREATE DATABASE power")
|
||||
if err != nil {
|
||||
log.Fatalln("failed to create database, err:", err)
|
||||
}
|
||||
_, err = taos.Exec("CREATE STABLE power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (location BINARY(64), groupId INT)")
|
||||
if err != nil {
|
||||
log.Fatalln("failed to create stable, err:", err)
|
||||
}
|
||||
{{#include docs/examples/go/demo/query/main.go:create_db_and_table}}
|
||||
```
|
||||
|
||||
### Insert data
|
||||
|
||||
<GoInsert />
|
||||
```go
|
||||
{{#include docs/examples/go/demo/query/main.go:insert_data}}
|
||||
```
|
||||
|
||||
### Querying data
|
||||
|
||||
<GoQuery />
|
||||
```go
|
||||
{{#include docs/examples/go/demo/query/main.go:query_data}}
|
||||
```
|
||||
|
||||
### execute SQL with reqId
|
||||
|
||||
This reqId can be used to request link tracing.
|
||||
<RequestId />
|
||||
|
||||
```go
|
||||
db, err := sql.Open("taosSql", "root:taosdata@tcp(localhost:6030)/")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer db.Close()
|
||||
ctx := context.WithValue(context.Background(), common.ReqIDKey, common.GetReqID())
|
||||
_, err = db.ExecContext(ctx, "create database if not exists example_taos_sql")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
{{#include docs/examples/go/demo/query/main.go:with_reqid}}
|
||||
```
|
||||
|
||||
### Writing data via parameter binding
|
||||
|
@ -280,375 +271,14 @@ if err != nil {
|
|||
<TabItem value="native" label="native connection">
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/taosdata/driver-go/v3/af"
|
||||
"github.com/taosdata/driver-go/v3/common"
|
||||
"github.com/taosdata/driver-go/v3/common/param"
|
||||
)
|
||||
|
||||
func main() {
|
||||
db, err := af.Open("", "root", "taosdata", "", 0)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer db.Close()
|
||||
_, err = db.Exec("create database if not exists example_stmt")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
_, err = db.Exec("create table if not exists example_stmt.tb1(ts timestamp," +
|
||||
"c1 bool," +
|
||||
"c2 tinyint," +
|
||||
"c3 smallint," +
|
||||
"c4 int," +
|
||||
"c5 bigint," +
|
||||
"c6 tinyint unsigned," +
|
||||
"c7 smallint unsigned," +
|
||||
"c8 int unsigned," +
|
||||
"c9 bigint unsigned," +
|
||||
"c10 float," +
|
||||
"c11 double," +
|
||||
"c12 binary(20)," +
|
||||
"c13 nchar(20)" +
|
||||
")")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
stmt := db.InsertStmt()
|
||||
err = stmt.Prepare("insert into example_stmt.tb1 values(?,?,?,?,?,?,?,?,?,?,?,?,?,?)")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
now := time.Now()
|
||||
params := make([]*param.Param, 14)
|
||||
params[0] = param.NewParam(2).
|
||||
AddTimestamp(now, common.PrecisionMilliSecond).
|
||||
AddTimestamp(now.Add(time.Second), common.PrecisionMilliSecond)
|
||||
params[1] = param.NewParam(2).AddBool(true).AddNull()
|
||||
params[2] = param.NewParam(2).AddTinyint(2).AddNull()
|
||||
params[3] = param.NewParam(2).AddSmallint(3).AddNull()
|
||||
params[4] = param.NewParam(2).AddInt(4).AddNull()
|
||||
params[5] = param.NewParam(2).AddBigint(5).AddNull()
|
||||
params[6] = param.NewParam(2).AddUTinyint(6).AddNull()
|
||||
params[7] = param.NewParam(2).AddUSmallint(7).AddNull()
|
||||
params[8] = param.NewParam(2).AddUInt(8).AddNull()
|
||||
params[9] = param.NewParam(2).AddUBigint(9).AddNull()
|
||||
params[10] = param.NewParam(2).AddFloat(10).AddNull()
|
||||
params[11] = param.NewParam(2).AddDouble(11).AddNull()
|
||||
params[12] = param.NewParam(2).AddBinary([]byte("binary")).AddNull()
|
||||
params[13] = param.NewParam(2).AddNchar("nchar").AddNull()
|
||||
|
||||
paramTypes := param.NewColumnType(14).
|
||||
AddTimestamp().
|
||||
AddBool().
|
||||
AddTinyint().
|
||||
AddSmallint().
|
||||
AddInt().
|
||||
AddBigint().
|
||||
AddUTinyint().
|
||||
AddUSmallint().
|
||||
AddUInt().
|
||||
AddUBigint().
|
||||
AddFloat().
|
||||
AddDouble().
|
||||
AddBinary(6).
|
||||
AddNchar(5)
|
||||
err = stmt.BindParam(params, paramTypes)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = stmt.AddBatch()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = stmt.Execute()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = stmt.Close()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
// select * from example_stmt.tb1
|
||||
}
|
||||
{{#include docs/examples/go/demo/stmt/main.go}}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="WebSocket" label="WebSocket connection">
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/taosdata/driver-go/v3/common"
|
||||
"github.com/taosdata/driver-go/v3/common/param"
|
||||
_ "github.com/taosdata/driver-go/v3/taosRestful"
|
||||
"github.com/taosdata/driver-go/v3/ws/stmt"
|
||||
)
|
||||
|
||||
func main() {
|
||||
db, err := sql.Open("taosRestful", "root:taosdata@http(localhost:6041)/")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer db.Close()
|
||||
prepareEnv(db)
|
||||
|
||||
config := stmt.NewConfig("ws://127.0.0.1:6041/rest/stmt", 0)
|
||||
config.SetConnectUser("root")
|
||||
config.SetConnectPass("taosdata")
|
||||
config.SetConnectDB("example_ws_stmt")
|
||||
config.SetMessageTimeout(common.DefaultMessageTimeout)
|
||||
config.SetWriteWait(common.DefaultWriteWait)
|
||||
config.SetErrorHandler(func(connector *stmt.Connector, err error) {
|
||||
panic(err)
|
||||
})
|
||||
config.SetCloseHandler(func() {
|
||||
fmt.Println("stmt connector closed")
|
||||
})
|
||||
|
||||
connector, err := stmt.NewConnector(config)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
now := time.Now()
|
||||
{
|
||||
stmt, err := connector.Init()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = stmt.Prepare("insert into ? using all_json tags(?) values(?,?,?,?,?,?,?,?,?,?,?,?,?,?)")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = stmt.SetTableName("tb1")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = stmt.SetTags(param.NewParam(1).AddJson([]byte(`{"tb":1}`)), param.NewColumnType(1).AddJson(0))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
params := []*param.Param{
|
||||
param.NewParam(3).AddTimestamp(now, 0).AddTimestamp(now.Add(time.Second), 0).AddTimestamp(now.Add(time.Second*2), 0),
|
||||
param.NewParam(3).AddBool(true).AddNull().AddBool(true),
|
||||
param.NewParam(3).AddTinyint(1).AddNull().AddTinyint(1),
|
||||
param.NewParam(3).AddSmallint(1).AddNull().AddSmallint(1),
|
||||
param.NewParam(3).AddInt(1).AddNull().AddInt(1),
|
||||
param.NewParam(3).AddBigint(1).AddNull().AddBigint(1),
|
||||
param.NewParam(3).AddUTinyint(1).AddNull().AddUTinyint(1),
|
||||
param.NewParam(3).AddUSmallint(1).AddNull().AddUSmallint(1),
|
||||
param.NewParam(3).AddUInt(1).AddNull().AddUInt(1),
|
||||
param.NewParam(3).AddUBigint(1).AddNull().AddUBigint(1),
|
||||
param.NewParam(3).AddFloat(1).AddNull().AddFloat(1),
|
||||
param.NewParam(3).AddDouble(1).AddNull().AddDouble(1),
|
||||
param.NewParam(3).AddBinary([]byte("test_binary")).AddNull().AddBinary([]byte("test_binary")),
|
||||
param.NewParam(3).AddNchar("test_nchar").AddNull().AddNchar("test_nchar"),
|
||||
}
|
||||
paramTypes := param.NewColumnType(14).
|
||||
AddTimestamp().
|
||||
AddBool().
|
||||
AddTinyint().
|
||||
AddSmallint().
|
||||
AddInt().
|
||||
AddBigint().
|
||||
AddUTinyint().
|
||||
AddUSmallint().
|
||||
AddUInt().
|
||||
AddUBigint().
|
||||
AddFloat().
|
||||
AddDouble().
|
||||
AddBinary(0).
|
||||
AddNchar(0)
|
||||
err = stmt.BindParam(params, paramTypes)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = stmt.AddBatch()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = stmt.Exec()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
affected := stmt.GetAffectedRows()
|
||||
fmt.Println("all_json affected rows:", affected)
|
||||
err = stmt.Close()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
{
|
||||
stmt, err := connector.Init()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = stmt.Prepare("insert into ? using all_all tags(?,?,?,?,?,?,?,?,?,?,?,?,?,?) values(?,?,?,?,?,?,?,?,?,?,?,?,?,?)")
|
||||
err = stmt.SetTableName("tb1")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
err = stmt.SetTableName("tb2")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = stmt.SetTags(
|
||||
param.NewParam(14).
|
||||
AddTimestamp(now, 0).
|
||||
AddBool(true).
|
||||
AddTinyint(2).
|
||||
AddSmallint(2).
|
||||
AddInt(2).
|
||||
AddBigint(2).
|
||||
AddUTinyint(2).
|
||||
AddUSmallint(2).
|
||||
AddUInt(2).
|
||||
AddUBigint(2).
|
||||
AddFloat(2).
|
||||
AddDouble(2).
|
||||
AddBinary([]byte("tb2")).
|
||||
AddNchar("tb2"),
|
||||
param.NewColumnType(14).
|
||||
AddTimestamp().
|
||||
AddBool().
|
||||
AddTinyint().
|
||||
AddSmallint().
|
||||
AddInt().
|
||||
AddBigint().
|
||||
AddUTinyint().
|
||||
AddUSmallint().
|
||||
AddUInt().
|
||||
AddUBigint().
|
||||
AddFloat().
|
||||
AddDouble().
|
||||
AddBinary(0).
|
||||
AddNchar(0),
|
||||
)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
params := []*param.Param{
|
||||
param.NewParam(3).AddTimestamp(now, 0).AddTimestamp(now.Add(time.Second), 0).AddTimestamp(now.Add(time.Second*2), 0),
|
||||
param.NewParam(3).AddBool(true).AddNull().AddBool(true),
|
||||
param.NewParam(3).AddTinyint(1).AddNull().AddTinyint(1),
|
||||
param.NewParam(3).AddSmallint(1).AddNull().AddSmallint(1),
|
||||
param.NewParam(3).AddInt(1).AddNull().AddInt(1),
|
||||
param.NewParam(3).AddBigint(1).AddNull().AddBigint(1),
|
||||
param.NewParam(3).AddUTinyint(1).AddNull().AddUTinyint(1),
|
||||
param.NewParam(3).AddUSmallint(1).AddNull().AddUSmallint(1),
|
||||
param.NewParam(3).AddUInt(1).AddNull().AddUInt(1),
|
||||
param.NewParam(3).AddUBigint(1).AddNull().AddUBigint(1),
|
||||
param.NewParam(3).AddFloat(1).AddNull().AddFloat(1),
|
||||
param.NewParam(3).AddDouble(1).AddNull().AddDouble(1),
|
||||
param.NewParam(3).AddBinary([]byte("test_binary")).AddNull().AddBinary([]byte("test_binary")),
|
||||
param.NewParam(3).AddNchar("test_nchar").AddNull().AddNchar("test_nchar"),
|
||||
}
|
||||
paramTypes := param.NewColumnType(14).
|
||||
AddTimestamp().
|
||||
AddBool().
|
||||
AddTinyint().
|
||||
AddSmallint().
|
||||
AddInt().
|
||||
AddBigint().
|
||||
AddUTinyint().
|
||||
AddUSmallint().
|
||||
AddUInt().
|
||||
AddUBigint().
|
||||
AddFloat().
|
||||
AddDouble().
|
||||
AddBinary(0).
|
||||
AddNchar(0)
|
||||
err = stmt.BindParam(params, paramTypes)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = stmt.AddBatch()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = stmt.Exec()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
affected := stmt.GetAffectedRows()
|
||||
fmt.Println("all_all affected rows:", affected)
|
||||
err = stmt.Close()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func prepareEnv(db *sql.DB) {
|
||||
steps := []string{
|
||||
"create database example_ws_stmt",
|
||||
"create table example_ws_stmt.all_json(ts timestamp," +
|
||||
"c1 bool," +
|
||||
"c2 tinyint," +
|
||||
"c3 smallint," +
|
||||
"c4 int," +
|
||||
"c5 bigint," +
|
||||
"c6 tinyint unsigned," +
|
||||
"c7 smallint unsigned," +
|
||||
"c8 int unsigned," +
|
||||
"c9 bigint unsigned," +
|
||||
"c10 float," +
|
||||
"c11 double," +
|
||||
"c12 binary(20)," +
|
||||
"c13 nchar(20)" +
|
||||
")" +
|
||||
"tags(t json)",
|
||||
"create table example_ws_stmt.all_all(" +
|
||||
"ts timestamp," +
|
||||
"c1 bool," +
|
||||
"c2 tinyint," +
|
||||
"c3 smallint," +
|
||||
"c4 int," +
|
||||
"c5 bigint," +
|
||||
"c6 tinyint unsigned," +
|
||||
"c7 smallint unsigned," +
|
||||
"c8 int unsigned," +
|
||||
"c9 bigint unsigned," +
|
||||
"c10 float," +
|
||||
"c11 double," +
|
||||
"c12 binary(20)," +
|
||||
"c13 nchar(20)" +
|
||||
")" +
|
||||
"tags(" +
|
||||
"tts timestamp," +
|
||||
"tc1 bool," +
|
||||
"tc2 tinyint," +
|
||||
"tc3 smallint," +
|
||||
"tc4 int," +
|
||||
"tc5 bigint," +
|
||||
"tc6 tinyint unsigned," +
|
||||
"tc7 smallint unsigned," +
|
||||
"tc8 int unsigned," +
|
||||
"tc9 bigint unsigned," +
|
||||
"tc10 float," +
|
||||
"tc11 double," +
|
||||
"tc12 binary(20)," +
|
||||
"tc13 nchar(20))",
|
||||
}
|
||||
for _, step := range steps {
|
||||
_, err := db.Exec(step)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{{#include docs/examples/go/demo/stmtws/main.go}}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
|
@ -661,98 +291,14 @@ func prepareEnv(db *sql.DB) {
|
|||
<TabItem value="native" label="native connection">
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/taosdata/driver-go/v3/af"
|
||||
)
|
||||
|
||||
func main() {
|
||||
conn, err := af.Open("localhost", "root", "taosdata", "", 6030)
|
||||
if err != nil {
|
||||
fmt.Println("fail to connect, err:", err)
|
||||
}
|
||||
defer conn.Close()
|
||||
_, err = conn.Exec("create database if not exists example")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
_, err = conn.Exec("use example")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
influxdbData := "st,t1=3i64,t2=4f64,t3=\"t3\" c1=3i64,c3=L\"passit\",c2=false,c4=4f64 1626006833639000000"
|
||||
err = conn.InfluxDBInsertLines([]string{influxdbData}, "ns")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
telnetData := "stb0_0 1626006833 4 host=host0 interface=eth0"
|
||||
err = conn.OpenTSDBInsertTelnetLines([]string{telnetData})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
jsonData := "{\"metric\": \"meter_current\",\"timestamp\": 1626846400,\"value\": 10.3, \"tags\": {\"groupid\": 2, \"location\": \"California.SanFrancisco\", \"id\": \"d1001\"}}"
|
||||
err = conn.OpenTSDBInsertJsonPayload(jsonData)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
{{#include docs/examples/go/demo/sml/main.go}}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="WebSocket" label="WebSocket connection">
|
||||
|
||||
```go
|
||||
import (
|
||||
"database/sql"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"github.com/taosdata/driver-go/v3/common"
|
||||
_ "github.com/taosdata/driver-go/v3/taosWS"
|
||||
"github.com/taosdata/driver-go/v3/ws/schemaless"
|
||||
)
|
||||
|
||||
func main() {
|
||||
db, err := sql.Open("taosWS", "root:taosdata@ws(localhost:6041)/")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer db.Close()
|
||||
_, err = db.Exec("create database if not exists schemaless_ws")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
s, err := schemaless.NewSchemaless(schemaless.NewConfig("ws://localhost:6041/rest/schemaless", 1,
|
||||
schemaless.SetDb("schemaless_ws"),
|
||||
schemaless.SetReadTimeout(10*time.Second),
|
||||
schemaless.SetWriteTimeout(10*time.Second),
|
||||
schemaless.SetUser("root"),
|
||||
schemaless.SetPassword("taosdata"),
|
||||
schemaless.SetErrorHandler(func(err error) {
|
||||
log.Fatal(err)
|
||||
}),
|
||||
))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
influxdbData := "st,t1=3i64,t2=4f64,t3=\"t3\" c1=3i64,c3=L\"passit\",c2=false,c4=4f64 1626006833639000000"
|
||||
telnetData := "stb0_0 1626006833 4 host=host0 interface=eth0"
|
||||
jsonData := "{\"metric\": \"meter_current\",\"timestamp\": 1626846400,\"value\": 10.3, \"tags\": {\"groupid\": 2, \"location\": \"California.SanFrancisco\", \"id\": \"d1001\"}}"
|
||||
|
||||
err = s.Insert(influxdbData, schemaless.InfluxDBLineProtocol, "ns", 0, common.GetReqID())
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = s.Insert(telnetData, schemaless.OpenTSDBTelnetLineProtocol, "ms", 0, common.GetReqID())
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = s.Insert(jsonData, schemaless.OpenTSDBJsonFormatProtocol, "ms", 0, common.GetReqID())
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
{{#include docs/examples/go/demo/smlws/main.go}}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
|
@ -774,89 +320,31 @@ The TDengine Go client library supports subscription functionality with the foll
|
|||
#### Create a Topic
|
||||
|
||||
```go
|
||||
db, err := af.Open("", "root", "taosdata", "", 0)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer db.Close()
|
||||
_, err = db.Exec("create database if not exists example_tmq WAL_RETENTION_PERIOD 86400")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
_, err = db.Exec("create topic if not exists example_tmq_topic as DATABASE example_tmq")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
{{#include docs/examples/go/demo/consumer/main.go:create_topic}}
|
||||
```
|
||||
|
||||
#### Create a Consumer
|
||||
|
||||
```go
|
||||
consumer, err := tmq.NewConsumer(&tmqcommon.ConfigMap{
|
||||
"group.id": "test",
|
||||
"auto.offset.reset": "latest",
|
||||
"td.connect.ip": "127.0.0.1",
|
||||
"td.connect.user": "root",
|
||||
"td.connect.pass": "taosdata",
|
||||
"td.connect.port": "6030",
|
||||
"client.id": "test_tmq_client",
|
||||
"enable.auto.commit": "false",
|
||||
"msg.with.table.name": "true",
|
||||
})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
{{#include docs/examples/go/demo/consumer/main.go:create_consumer}}
|
||||
```
|
||||
|
||||
#### Subscribe to consume data
|
||||
|
||||
```go
|
||||
err = consumer.Subscribe("example_tmq_topic", nil)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for i := 0; i < 5; i++ {
|
||||
ev := consumer.Poll(500)
|
||||
if ev != nil {
|
||||
switch e := ev.(type) {
|
||||
case *tmqcommon.DataMessage:
|
||||
fmt.Printf("get message:%v\n", e)
|
||||
case tmqcommon.Error:
|
||||
fmt.Fprintf(os.Stderr, "%% Error: %v: %v\n", e.Code(), e)
|
||||
panic(e)
|
||||
}
|
||||
consumer.Commit()
|
||||
}
|
||||
}
|
||||
{{#include docs/examples/go/demo/consumer/main.go:poll_data}}
|
||||
```
|
||||
|
||||
#### Assignment subscription Offset
|
||||
|
||||
```go
|
||||
partitions, err := consumer.Assignment()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for i := 0; i < len(partitions); i++ {
|
||||
fmt.Println(partitions[i])
|
||||
err = consumer.Seek(tmqcommon.TopicPartition{
|
||||
Topic: partitions[i].Topic,
|
||||
Partition: partitions[i].Partition,
|
||||
Offset: 0,
|
||||
}, 0)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
{{#include docs/examples/go/demo/consumer/main.go:consumer_seek}}
|
||||
```
|
||||
|
||||
#### Close subscriptions
|
||||
|
||||
```go
|
||||
err = consumer.Close()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
{{#include docs/examples/go/demo/consumer/main.go:consumer_close}}
|
||||
```
|
||||
|
||||
#### Full Sample Code
|
||||
|
@ -865,232 +353,14 @@ The TDengine Go client library supports subscription functionality with the foll
|
|||
<TabItem value="native" label="native connection">
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/taosdata/driver-go/v3/af"
|
||||
"github.com/taosdata/driver-go/v3/af/tmq"
|
||||
tmqcommon "github.com/taosdata/driver-go/v3/common/tmq"
|
||||
)
|
||||
|
||||
func main() {
|
||||
db, err := af.Open("", "root", "taosdata", "", 0)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer db.Close()
|
||||
_, err = db.Exec("create database if not exists example_tmq WAL_RETENTION_PERIOD 86400")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
_, err = db.Exec("create topic if not exists example_tmq_topic as DATABASE example_tmq")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
consumer, err := tmq.NewConsumer(&tmqcommon.ConfigMap{
|
||||
"group.id": "test",
|
||||
"auto.offset.reset": "latest",
|
||||
"td.connect.ip": "127.0.0.1",
|
||||
"td.connect.user": "root",
|
||||
"td.connect.pass": "taosdata",
|
||||
"td.connect.port": "6030",
|
||||
"client.id": "test_tmq_client",
|
||||
"enable.auto.commit": "false",
|
||||
"msg.with.table.name": "true",
|
||||
})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = consumer.Subscribe("example_tmq_topic", nil)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
_, err = db.Exec("create table example_tmq.t1 (ts timestamp,v int)")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
go func() {
|
||||
for {
|
||||
_, err = db.Exec("insert into example_tmq.t1 values(now,1)")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
time.Sleep(time.Millisecond * 100)
|
||||
}
|
||||
}()
|
||||
|
||||
for i := 0; i < 5; i++ {
|
||||
ev := consumer.Poll(500)
|
||||
if ev != nil {
|
||||
switch e := ev.(type) {
|
||||
case *tmqcommon.DataMessage:
|
||||
fmt.Printf("get message:%v\n", e)
|
||||
case tmqcommon.Error:
|
||||
fmt.Fprintf(os.Stderr, "%% Error: %v: %v\n", e.Code(), e)
|
||||
panic(e)
|
||||
}
|
||||
consumer.Commit()
|
||||
}
|
||||
}
|
||||
partitions, err := consumer.Assignment()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for i := 0; i < len(partitions); i++ {
|
||||
fmt.Println(partitions[i])
|
||||
err = consumer.Seek(tmqcommon.TopicPartition{
|
||||
Topic: partitions[i].Topic,
|
||||
Partition: partitions[i].Partition,
|
||||
Offset: 0,
|
||||
}, 0)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
partitions, err = consumer.Assignment()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for i := 0; i < len(partitions); i++ {
|
||||
fmt.Println(partitions[i])
|
||||
}
|
||||
|
||||
err = consumer.Close()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
{{#include docs/examples/go/demo/consumer/main.go}}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="WebSocket" label="WebSocket connection">
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/taosdata/driver-go/v3/common"
|
||||
tmqcommon "github.com/taosdata/driver-go/v3/common/tmq"
|
||||
_ "github.com/taosdata/driver-go/v3/taosRestful"
|
||||
"github.com/taosdata/driver-go/v3/ws/tmq"
|
||||
)
|
||||
|
||||
func main() {
|
||||
db, err := sql.Open("taosRestful", "root:taosdata@http(localhost:6041)/")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer db.Close()
|
||||
prepareEnv(db)
|
||||
consumer, err := tmq.NewConsumer(&tmqcommon.ConfigMap{
|
||||
"ws.url": "ws://127.0.0.1:6041/rest/tmq",
|
||||
"ws.message.channelLen": uint(0),
|
||||
"ws.message.timeout": common.DefaultMessageTimeout,
|
||||
"ws.message.writeWait": common.DefaultWriteWait,
|
||||
"td.connect.user": "root",
|
||||
"td.connect.pass": "taosdata",
|
||||
"group.id": "example",
|
||||
"client.id": "example_consumer",
|
||||
"auto.offset.reset": "latest",
|
||||
})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = consumer.Subscribe("example_ws_tmq_topic", nil)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
_, err = db.Exec("create table example_ws_tmq.t_all(ts timestamp," +
|
||||
"c1 bool," +
|
||||
"c2 tinyint," +
|
||||
"c3 smallint," +
|
||||
"c4 int," +
|
||||
"c5 bigint," +
|
||||
"c6 tinyint unsigned," +
|
||||
"c7 smallint unsigned," +
|
||||
"c8 int unsigned," +
|
||||
"c9 bigint unsigned," +
|
||||
"c10 float," +
|
||||
"c11 double," +
|
||||
"c12 binary(20)," +
|
||||
"c13 nchar(20)" +
|
||||
")")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
go func() {
|
||||
for {
|
||||
_, err = db.Exec("insert into example_ws_tmq.t_all values(now,true,2,3,4,5,6,7,8,9,10.123,11.123,'binary','nchar')")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
time.Sleep(time.Millisecond * 100)
|
||||
}
|
||||
|
||||
}()
|
||||
for i := 0; i < 5; i++ {
|
||||
ev := consumer.Poll(500)
|
||||
if ev != nil {
|
||||
switch e := ev.(type) {
|
||||
case *tmqcommon.DataMessage:
|
||||
fmt.Printf("get message:%v\n", e)
|
||||
case tmqcommon.Error:
|
||||
fmt.Printf("%% Error: %v: %v\n", e.Code(), e)
|
||||
panic(e)
|
||||
}
|
||||
consumer.Commit()
|
||||
}
|
||||
}
|
||||
partitions, err := consumer.Assignment()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for i := 0; i < len(partitions); i++ {
|
||||
fmt.Println(partitions[i])
|
||||
err = consumer.Seek(tmqcommon.TopicPartition{
|
||||
Topic: partitions[i].Topic,
|
||||
Partition: partitions[i].Partition,
|
||||
Offset: 0,
|
||||
}, 0)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
partitions, err = consumer.Assignment()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for i := 0; i < len(partitions); i++ {
|
||||
fmt.Println(partitions[i])
|
||||
}
|
||||
|
||||
err = consumer.Close()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func prepareEnv(db *sql.DB) {
|
||||
_, err := db.Exec("create database example_ws_tmq WAL_RETENTION_PERIOD 86400")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
_, err = db.Exec("create topic example_ws_tmq_topic as database example_ws_tmq")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
{{#include docs/examples/go/demo/consumerws/main.go}}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
|
|
|
@ -13,15 +13,24 @@ import RustInsert from "../07-develop/03-insert-data/_rust_sql.mdx"
|
|||
import RustBind from "../07-develop/03-insert-data/_rust_stmt.mdx"
|
||||
import RustSml from "../07-develop/03-insert-data/_rust_schemaless.mdx"
|
||||
import RustQuery from "../07-develop/04-query-data/_rust.mdx"
|
||||
import RequestId from "./_request_id.mdx";
|
||||
|
||||
[](https://crates.io/crates/taos)  [](https://docs.rs/taos)
|
||||
|
||||
`taos` is the official Rust client library for TDengine. Rust developers can develop applications to access the TDengine instance data.
|
||||
|
||||
`taos` provides two ways to establish connections. One is the **Native Connection**, which connects to TDengine instances via the TDengine client driver (taosc). The other is the **WebSocket connection**, which connects to TDengine instances via the WebSocket interface provided by taosAdapter. You can specify a connection type with Cargo features. By default, both types are supported. The Websocket connection can be used on any platform. The native connection can be used on any platform that the TDengine Client supports.
|
||||
|
||||
The source code for the Rust client library is located on [GitHub](https://github.com/taosdata/taos-connector-rust).
|
||||
|
||||
## Connection types
|
||||
|
||||
`taos` provides two ways to establish connections, among which we recommend using **websocket connection**.
|
||||
- **Native Connection**, which connects to TDengine instances via the TDengine client driver (taosc).
|
||||
- **WebSocket connection**, which connects to TDengine instances via the WebSocket interface provided by taosAdapter.
|
||||
|
||||
You can specify a connection type with Cargo features. By default, both types are supported.
|
||||
|
||||
For a detailed introduction of the connection types, please refer to: [Establish Connection](../../develop/connect/#establish-connection)
|
||||
|
||||
## Supported platforms
|
||||
|
||||
Native connections are supported on the same platforms as the TDengine client driver.
|
||||
|
@ -31,8 +40,11 @@ Websocket connections are supported on all platforms that can run Go.
|
|||
|
||||
| connector-rust version | TDengine version | major features |
|
||||
| :----------------: | :--------------: | :--------------------------------------------------: |
|
||||
| v0.9.2 | 3.0.7.0 or later | STMT: Get tag_fields and col_fields under ws. |
|
||||
| v0.8.12 | 3.0.5.0 | TMQ: Get consuming progress and seek offset to consume. |
|
||||
| v0.12.0 | 3.2.3.0 or later | WS supports compression |
|
||||
| v0.11.0 | 3.2.0.0 | TMQ feature optimization |
|
||||
| v0.10.0 | 3.1.0.0 | WS endpoint changes |
|
||||
| v0.9.2 | 3.0.7.0 | STMT: Get tag_fields and col_fields under ws. |
|
||||
| v0.8.12 | 3.0.5.0 | TMQ: Get consuming progress and seek offset to consume. |
|
||||
| v0.8.0 | 3.0.4.0 | Support schemaless insert. |
|
||||
| v0.7.6 | 3.0.3.0 | Support req_id in query. |
|
||||
| v0.6.0 | 3.0.0.0 | Base features. |
|
||||
|
@ -269,52 +281,28 @@ There are two ways to query data: Using built-in types or the [serde](https://se
|
|||
### Create database and tables
|
||||
|
||||
```rust
|
||||
use taos::*;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> anyhow::Result<()> {
|
||||
let dsn = "taos://localhost:6030";
|
||||
let builder = TaosBuilder::from_dsn(dsn)?;
|
||||
|
||||
let taos = builder.build()?;
|
||||
|
||||
let db = "query";
|
||||
|
||||
// create database
|
||||
taos.exec_many([
|
||||
format!("DROP DATABASE IF EXISTS `{db}`"),
|
||||
format!("CREATE DATABASE `{db}`"),
|
||||
format!("USE `{db}`"),
|
||||
])
|
||||
.await?;
|
||||
|
||||
// create table
|
||||
taos.exec_many([
|
||||
// create super table
|
||||
"CREATE TABLE `meters` (`ts` TIMESTAMP, `current` FLOAT, `voltage` INT, `phase` FLOAT) \
|
||||
TAGS (`groupid` INT, `location` BINARY(16))",
|
||||
// create child table
|
||||
"CREATE TABLE `d0` USING `meters` TAGS(0, 'Los Angles')",
|
||||
]).await?;
|
||||
}
|
||||
{{#include docs/examples/rust/nativeexample/examples/query.rs:create_db_and_table}}
|
||||
```
|
||||
|
||||
> The query is consistent with operating a relational database. When using subscripts to get the contents of the returned fields, you have to start from 1. However, we recommend using the field names to get the values of the fields in the result set.
|
||||
|
||||
### Insert data
|
||||
|
||||
<RustInsert />
|
||||
|
||||
```rust
|
||||
{{#include docs/examples/rust/nativeexample/examples/query.rs:insert_data}}
|
||||
```
|
||||
### Query data
|
||||
|
||||
<RustQuery />
|
||||
```rust
|
||||
{{#include docs/examples/rust/nativeexample/examples/query.rs:query_data}}
|
||||
```
|
||||
|
||||
### execute SQL with req_id
|
||||
|
||||
This req_id can be used to request link tracing.
|
||||
<RequestId />
|
||||
|
||||
```rust
|
||||
let rs = taos.query_with_req_id("select * from stable where tag1 is null", 1)?;
|
||||
{{#include docs/examples/rust/nativeexample/examples/query.rs:query_with_req_id}}
|
||||
```
|
||||
|
||||
### Writing data via parameter binding
|
||||
|
@ -323,13 +311,17 @@ TDengine has significantly improved the bind APIs to support data writing (INSER
|
|||
|
||||
Parameter binding details see [API Reference](#bind-interface)
|
||||
|
||||
<RustBind />
|
||||
```rust
|
||||
{{#include docs/examples/rust/nativeexample/examples/stmt.rs}}
|
||||
```
|
||||
|
||||
### Schemaless Writing
|
||||
|
||||
TDengine supports schemaless writing. It is compatible with InfluxDB's Line Protocol, OpenTSDB's telnet line protocol, and OpenTSDB's JSON format protocol. For more information, see [Schemaless Writing](../../reference/schemaless/).
|
||||
|
||||
<RustSml />
|
||||
```rust
|
||||
{{#include docs/examples/rust/nativeexample/examples/schemaless.rs}}
|
||||
```
|
||||
|
||||
### Schemaless with req_id
|
||||
|
||||
|
@ -352,25 +344,15 @@ TDengine starts subscriptions through [TMQ](../../taos-sql/tmq/).
|
|||
#### Create a Topic
|
||||
|
||||
```rust
|
||||
taos.exec_many([
|
||||
// create topic for subscription
|
||||
format!("CREATE TOPIC tmq_meters with META AS DATABASE {db}")
|
||||
])
|
||||
.await?;
|
||||
{{#include docs/examples/rust/nativeexample/examples/tmq.rs:create_topic}}
|
||||
```
|
||||
|
||||
#### Create a Consumer
|
||||
|
||||
You create a TMQ connection by using a DSN.
|
||||
|
||||
```rust
|
||||
let tmq = TmqBuilder::from_dsn("taos://localhost:6030/?group.id=test")?;
|
||||
```
|
||||
|
||||
Create a consumer:
|
||||
|
||||
```rust
|
||||
let mut consumer = tmq.build()?;
|
||||
{{#include docs/examples/rust/nativeexample/examples/tmq.rs:create_consumer}}
|
||||
```
|
||||
|
||||
#### Subscribe to consume data
|
||||
|
@ -378,40 +360,13 @@ let mut consumer = tmq.build()?;
|
|||
A single consumer can subscribe to one or more topics.
|
||||
|
||||
```rust
|
||||
consumer.subscribe(["tmq_meters"]).await?;
|
||||
{{#include docs/examples/rust/nativeexample/examples/tmq.rs:subscribe}}
|
||||
```
|
||||
|
||||
The TMQ is of [futures::Stream](https://docs.rs/futures/latest/futures/stream/index.html) type. You can use the corresponding API to consume each message in the queue and then use `.commit` to mark them as consumed.
|
||||
|
||||
```rust
|
||||
{
|
||||
let mut stream = consumer.stream();
|
||||
|
||||
while let Some((offset, message)) = stream.try_next().await? {
|
||||
// get information from offset
|
||||
|
||||
// the topic
|
||||
let topic = offset.topic();
|
||||
// the vgroup id, like partition id in kafka.
|
||||
let vgroup_id = offset.vgroup_id();
|
||||
println!("* in vgroup id {vgroup_id} of topic {topic}\n");
|
||||
|
||||
if let Some(data) = message.into_data() {
|
||||
while let Some(block) = data.fetch_raw_block().await? {
|
||||
// one block for one table, get table name if needed
|
||||
let name = block.table_name();
|
||||
let records: Vec<Record> = block.deserialize().try_collect()?;
|
||||
println!(
|
||||
"** table: {}, got {} records: {:#?}\n",
|
||||
name.unwrap(),
|
||||
records.len(),
|
||||
records
|
||||
);
|
||||
}
|
||||
}
|
||||
consumer.commit(offset).await?;
|
||||
}
|
||||
}
|
||||
{{#include docs/examples/rust/nativeexample/examples/tmq.rs:consume}}
|
||||
```
|
||||
|
||||
Get assignments:
|
||||
|
@ -419,7 +374,7 @@ Get assignments:
|
|||
Version requirements connector-rust >= v0.8.8, TDengine >= 3.0.5.0
|
||||
|
||||
```rust
|
||||
let assignments = consumer.assignments().await.unwrap();
|
||||
{{#include docs/examples/rust/nativeexample/examples/tmq.rs:assignments}}
|
||||
```
|
||||
|
||||
#### Assignment subscription Offset
|
||||
|
@ -429,13 +384,13 @@ Seek offset:
|
|||
Version requirements connector-rust >= v0.8.8, TDengine >= 3.0.5.0
|
||||
|
||||
```rust
|
||||
consumer.offset_seek(topic, vgroup_id, offset).await;
|
||||
{{#include docs/examples/rust/nativeexample/examples/tmq.rs:seek_offset}}
|
||||
```
|
||||
|
||||
#### Close subscriptions
|
||||
|
||||
```rust
|
||||
consumer.unsubscribe().await;
|
||||
{{#include docs/examples/rust/nativeexample/examples/tmq.rs:unsubscribe}}
|
||||
```
|
||||
|
||||
The following parameters can be configured for the TMQ DSN. Only `group.id` is mandatory.
|
||||
|
|
|
@ -6,15 +6,25 @@ description: This document describes taospy, the TDengine Python client library.
|
|||
|
||||
import Tabs from "@theme/Tabs";
|
||||
import TabItem from "@theme/TabItem";
|
||||
import RequestId from "./_request_id.mdx";
|
||||
|
||||
`taospy` is the official Python client library for TDengine. taospy provides a rich API that makes it easy for Python applications to use TDengine.
|
||||
|
||||
The source code for the Python client library is hosted on [GitHub](https://github.com/taosdata/taos-connector-python).
|
||||
|
||||
## Connection types
|
||||
|
||||
`taospy` mainly provides 3 connection types, among which we recommend using **websocket connection**.
|
||||
- **Native connection**, which correspond to the `taos` modules of the `taospy` package, connects to TDengine instances natively through the TDengine client driver (taosc), supporting data writing, querying, subscriptions, schemaless writing, and bind interface.
|
||||
- **REST connection**, which correspond to the `taosrest` modules of the `taospy` package, which is implemented through taosAdapter. Some features like schemaless and subscriptions are not supported.
|
||||
- **Websocket connection** `taos-ws-py` is an optional package to enable using WebSocket to connect TDengine, which is implemented through taosAdapter. The set of features implemented by the WebSocket connection differs slightly from those implemented by the native connection.
|
||||
|
||||
For a detailed introduction of the connection types, please refer to: [Establish Connection](../../develop/connect/#establish-connection)
|
||||
|
||||
`taospy` is the official Python client library for TDengine. taospy provides a rich API that makes it easy for Python applications to use TDengine. `taospy` wraps both the [native interface](../cpp) and [REST interface](../../reference/rest-api) of TDengine, which correspond to the `taos` and `taosrest` modules of the `taospy` package, respectively.
|
||||
In addition to wrapping the native and REST interfaces, `taospy` also provides a set of programming interfaces that conforms to the [Python Data Access Specification (PEP 249)](https://peps.python.org/pep-0249/). It is easy to integrate `taospy` with many third-party tools, such as [SQLAlchemy](https://www.sqlalchemy.org/) and [pandas](https://pandas.pydata.org/).
|
||||
|
||||
`taos-ws-py` is an optional package to enable using WebSocket to connect TDengine.
|
||||
|
||||
The direct connection to the server using the native interface provided by the client driver is referred to hereinafter as a "native connection"; the connection to the server using the REST or WebSocket interface provided by taosAdapter is referred to hereinafter as a "REST connection" or "WebSocket connection".
|
||||
|
||||
The source code for the Python client library is hosted on [GitHub](https://github.com/taosdata/taos-connector-python).
|
||||
## Supported platforms
|
||||
|
||||
- The [supported platforms](../#supported-platforms) for the native connection are the same as the ones supported by the TDengine client.
|
||||
|
@ -348,13 +358,7 @@ If the configuration parameters are duplicated in the parameters or client confi
|
|||
<TabItem value="native" label="native connection">
|
||||
|
||||
```python
|
||||
conn = taos.connect()
|
||||
# Execute a sql, ignore the result set, just get affected rows. It's useful for DDL and DML statement.
|
||||
conn.execute("DROP DATABASE IF EXISTS test")
|
||||
conn.execute("CREATE DATABASE test")
|
||||
# change database. same as execute "USE db"
|
||||
conn.select_db("test")
|
||||
conn.execute("CREATE STABLE weather(ts TIMESTAMP, temperature FLOAT) TAGS (location INT)")
|
||||
{{#include docs/examples/python/create_db_native.py}}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
|
@ -362,12 +366,7 @@ conn.execute("CREATE STABLE weather(ts TIMESTAMP, temperature FLOAT) TAGS (locat
|
|||
<TabItem value="rest" label="REST connection">
|
||||
|
||||
```python
|
||||
conn = taosrest.connect(url="http://localhost:6041")
|
||||
# Execute a sql, ignore the result set, just get affected rows. It's useful for DDL and DML statement.
|
||||
conn.execute("DROP DATABASE IF EXISTS test")
|
||||
conn.execute("CREATE DATABASE test")
|
||||
conn.execute("USE test")
|
||||
conn.execute("CREATE STABLE weather(ts TIMESTAMP, temperature FLOAT) TAGS (location INT)")
|
||||
{{#include docs/examples/python/create_db_rest.py}}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
|
@ -375,12 +374,7 @@ conn.execute("CREATE STABLE weather(ts TIMESTAMP, temperature FLOAT) TAGS (locat
|
|||
<TabItem value="websocket" label="WebSocket connection">
|
||||
|
||||
```python
|
||||
conn = taosws.connect("taosws://localhost:6041")
|
||||
# Execute a sql, ignore the result set, just get affected rows. It's useful for DDL and DML statement.
|
||||
conn.execute("DROP DATABASE IF EXISTS test")
|
||||
conn.execute("CREATE DATABASE test")
|
||||
conn.execute("USE test")
|
||||
conn.execute("CREATE STABLE weather(ts TIMESTAMP, temperature FLOAT) TAGS (location INT)")
|
||||
{{#include docs/examples/python/create_db_ws.py}}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
|
@ -388,100 +382,35 @@ conn.execute("CREATE STABLE weather(ts TIMESTAMP, temperature FLOAT) TAGS (locat
|
|||
|
||||
### Insert data
|
||||
|
||||
```python
|
||||
conn.execute("INSERT INTO t1 USING weather TAGS(1) VALUES (now, 23.5) (now+1m, 23.5) (now+2m, 24.4)")
|
||||
```
|
||||
|
||||
:::
|
||||
now is an internal function. The default is the current time of the client's computer. now + 1s represents the current time of the client plus 1 second, followed by the number representing the unit of time: a (milliseconds), s (seconds), m (minutes), h (hours), d (days), w (weeks), n (months), y (years).
|
||||
:::
|
||||
|
||||
|
||||
### Basic Usage
|
||||
|
||||
<Tabs defaultValue="rest">
|
||||
<TabItem value="native" label="native connection">
|
||||
|
||||
##### TaosConnection class
|
||||
|
||||
The `TaosConnection` class contains both an implementation of the PEP249 Connection interface (e.g., the `cursor()` method and the `close()` method) and many extensions (e.g., the `execute()`, `query()`, `schemaless_insert()`, and `subscribe()` methods).
|
||||
|
||||
```python title="execute method"
|
||||
{{#include docs/examples/python/connection_usage_native_reference.py:insert}}
|
||||
```python
|
||||
{{#include docs/examples/python/insert_native.py:insert}}
|
||||
```
|
||||
|
||||
```python title="query method"
|
||||
{{#include docs/examples/python/connection_usage_native_reference.py:query}}
|
||||
```
|
||||
|
||||
:::tip
|
||||
The queried results can only be fetched once. For example, only one of `fetch_all()` and `fetch_all_into_dict()` can be used in the example above. Repeated fetches will result in an empty list.
|
||||
:::
|
||||
|
||||
##### Use of TaosResult class
|
||||
|
||||
In the above example of using the `TaosConnection` class, we have shown two ways to get the result of a query: `fetch_all()` and `fetch_all_into_dict()`. In addition, `TaosResult` also provides methods to iterate through the result set by rows (`rows_iter`) or by data blocks (`blocks_iter`). Using these two methods will be more efficient in scenarios where the query has a large amount of data.
|
||||
|
||||
```python title="blocks_iter method"
|
||||
{{#include docs/examples/python/result_set_examples.py}}
|
||||
```
|
||||
##### Use of the TaosCursor class
|
||||
|
||||
The `TaosConnection` class and the `TaosResult` class already implement all the functionality of the native interface. If you are familiar with the interfaces in the PEP249 specification, you can also use the methods provided by the `TaosCursor` class.
|
||||
|
||||
```python title="Use of TaosCursor"
|
||||
{{#include docs/examples/python/cursor_usage_native_reference.py}}
|
||||
```
|
||||
|
||||
:::note
|
||||
The TaosCursor class uses native connections for write and query operations. In a client-side multi-threaded scenario, this cursor instance must remain thread exclusive and cannot be shared across threads for use, otherwise, it will result in errors in the returned results.
|
||||
|
||||
The best practice for TaosCursor is to create a cursor at the beginning of a query and close it immediately after use. Please avoid reusing the same cursor for multiple executions.
|
||||
:::
|
||||
|
||||
</TabItem>
|
||||
|
||||
<TabItem value="rest" label="REST connection">
|
||||
|
||||
##### Use of the RestClient class
|
||||
|
||||
The `RestClient` class is a direct wrapper for the [REST API](../../reference/rest-api). It contains only a `sql()` method for executing arbitrary SQL statements and returning the result.
|
||||
|
||||
```python title="Use of RestClient"
|
||||
{{#include docs/examples/python/rest_client_example.py}}
|
||||
```python
|
||||
{{#include docs/examples/python/insert_rest.py:insert}}
|
||||
```
|
||||
|
||||
For a more detailed description of the `sql()` method, please refer to [RestClient](https://docs.taosdata.com/api/taospy/taosrest/restclient.html).
|
||||
|
||||
##### Use of TaosRestCursor class
|
||||
|
||||
The `TaosRestCursor` class is an implementation of the PEP249 Cursor interface.
|
||||
|
||||
```python title="Use of TaosRestCursor"
|
||||
{{#include docs/examples/python/connect_rest_examples.py:basic}}
|
||||
```
|
||||
- `cursor.execute`: Used to execute arbitrary SQL statements.
|
||||
- `cursor.rowcount` : For write operations, returns the number of successful rows written. For query operations, returns the number of rows in the result set.
|
||||
- `cursor.description` : Returns the description of the field. Please refer to [TaosRestCursor](https://docs.taosdata.com/api/taospy/taosrest/cursor.html) for the specific format of the description information.
|
||||
|
||||
:::note
|
||||
The best practice for TaosRestCursor is to create a cursor at the beginning of a query and close it immediately after use. Please avoid reusing the same cursor for multiple executions.
|
||||
:::
|
||||
|
||||
</TabItem>
|
||||
|
||||
<TabItem value="websocket" label="WebSocket connection">
|
||||
|
||||
The `Connection` class contains both an implementation of the PEP249 Connection interface (e.g., the `cursor()` method and the `close()` method) and many extensions (e.g., the `execute()`, `query()`, `schemaless_insert()`, and `subscribe()` methods).
|
||||
|
||||
```python
|
||||
{{#include docs/examples/python/connect_websocket_examples.py:basic}}
|
||||
{{#include docs/examples/python/insert_ws.py:insert}}
|
||||
```
|
||||
|
||||
- `conn.execute`: can use to execute arbitrary SQL statements, and return the number of rows affected.
|
||||
- `conn.query`: can use to execute query SQL statements, and return the query results.
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
> NOW is an internal function. The default is the current time of the client's computer.
|
||||
> `NOW + 1s` represents the current time of the client plus 1 second, followed by the number representing the unit of time: a (milliseconds), s (seconds), m (minutes), h (hours), d (days), w (weeks), n (months), y (years).
|
||||
|
||||
### Querying Data
|
||||
|
||||
<Tabs defaultValue="rest">
|
||||
|
@ -490,7 +419,7 @@ The `Connection` class contains both an implementation of the PEP249 Connection
|
|||
The `query` method of the `TaosConnection` class can be used to query data and return the result data of type `TaosResult`.
|
||||
|
||||
```python
|
||||
{{#include docs/examples/python/connection_usage_native_reference.py:query}}
|
||||
{{#include docs/examples/python/insert_native.py:query}}
|
||||
```
|
||||
|
||||
:::tip
|
||||
|
@ -504,7 +433,7 @@ The queried results can only be fetched once. For example, only one of `fetch_al
|
|||
The `RestClient` class is a direct wrapper for the [REST API](../../reference/rest-api). It contains only a `sql()` method for executing arbitrary SQL statements and returning the result.
|
||||
|
||||
```python
|
||||
{{#include docs/examples/python/rest_client_example.py}}
|
||||
{{#include docs/examples/python/insert_rest.py:query}}
|
||||
```
|
||||
|
||||
For a more detailed description of the `sql()` method, please refer to [RestClient](https://docs.taosdata.com/api/taospy/taosrest/restclient.html).
|
||||
|
@ -516,7 +445,7 @@ For a more detailed description of the `sql()` method, please refer to [RestClie
|
|||
The `query` method of the `TaosConnection` class can be used to query data and return the result data of type `TaosResult`.
|
||||
|
||||
```python
|
||||
{{#include docs/examples/python/connect_websocket_examples.py:basic}}
|
||||
{{#include docs/examples/python/insert_ws.py:query}}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
|
@ -524,61 +453,25 @@ The `query` method of the `TaosConnection` class can be used to query data and r
|
|||
|
||||
### Execute SQL with reqId
|
||||
|
||||
By using the optional req_id parameter, you can specify a request ID that can be used for tracing.
|
||||
<RequestId />
|
||||
|
||||
<Tabs defaultValue="rest">
|
||||
<TabItem value="native" label="native connection">
|
||||
|
||||
##### TaosConnection class
|
||||
|
||||
As the way to connect introduced above but add `req_id` argument.
|
||||
|
||||
```python title="execute method"
|
||||
{{#include docs/examples/python/connection_usage_native_reference_with_req_id.py:insert}}
|
||||
```
|
||||
|
||||
```python title="query method"
|
||||
{{#include docs/examples/python/connection_usage_native_reference_with_req_id.py:query}}
|
||||
```
|
||||
|
||||
##### Use of TaosResult class
|
||||
|
||||
As the way to fetch data introduced above but add `req_id` argument.
|
||||
|
||||
```python title="blocks_iter method"
|
||||
{{#include docs/examples/python/result_set_with_req_id_examples.py}}
|
||||
```
|
||||
##### Use of the TaosCursor class
|
||||
|
||||
The `TaosConnection` class and the `TaosResult` class already implement all the functionality of the native interface. If you are familiar with the interfaces in the PEP249 specification, you can also use the methods provided by the `TaosCursor` class.
|
||||
|
||||
```python title="Use of TaosCursor"
|
||||
{{#include docs/examples/python/cursor_usage_native_reference_with_req_id.py}}
|
||||
```python
|
||||
{{#include docs/examples/python/insert_native.py:req_id}}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="rest" label="REST connection">
|
||||
|
||||
##### Use of the RestClient class
|
||||
|
||||
The `RestClient` class is a direct wrapper for the [REST API](../../reference/rest-api). It contains only a `sql()` method for executing arbitrary SQL statements and returning the result.
|
||||
|
||||
```python title="Use of RestClient"
|
||||
{{#include docs/examples/python/rest_client_with_req_id_example.py}}
|
||||
```
|
||||
|
||||
For a more detailed description of the `sql()` method, please refer to [RestClient](https://docs.taosdata.com/api/taospy/taosrest/restclient.html).
|
||||
|
||||
##### Use of TaosRestCursor class
|
||||
|
||||
As the way to connect introduced above but add `req_id` argument.
|
||||
|
||||
```python title="Use of TaosRestCursor"
|
||||
{{#include docs/examples/python/connect_rest_with_req_id_examples.py:basic}}
|
||||
```python
|
||||
{{#include docs/examples/python/insert_rest.py:req_id}}
|
||||
```
|
||||
- `cursor.execute`: Used to execute arbitrary SQL statements.
|
||||
- `cursor.rowcount` : For write operations, returns the number of successful rows written. For query operations, returns the number of rows in the result set.
|
||||
- `cursor.description` : Returns the description of the field. Please refer to [TaosRestCursor](https://docs.taosdata.com/api/taospy/taosrest/cursor.html) for the specific format of the description information.
|
||||
|
||||
</TabItem>
|
||||
|
||||
|
@ -587,36 +480,7 @@ As the way to connect introduced above but add `req_id` argument.
|
|||
As the way to connect introduced above but add `req_id` argument.
|
||||
|
||||
```python
|
||||
{{#include docs/examples/python/connect_websocket_with_req_id_examples.py:basic}}
|
||||
```
|
||||
|
||||
- `conn.execute`: can use to execute arbitrary SQL statements, and return the number of rows affected.
|
||||
- `conn.query`: can use to execute query SQL statements, and return the query results.
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
### Used with pandas
|
||||
|
||||
<Tabs defaultValue="rest">
|
||||
<TabItem value="native" label="native connection">
|
||||
|
||||
```python
|
||||
{{#include docs/examples/python/conn_native_pandas.py}}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="rest" label="REST connection">
|
||||
|
||||
```python
|
||||
{{#include docs/examples/python/conn_rest_pandas.py}}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="websocket" label="WebSocket connection">
|
||||
|
||||
```python
|
||||
{{#include docs/examples/python/conn_websocket_pandas.py}}
|
||||
{{#include docs/examples/python/insert_ws.py:req_id}}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
|
@ -629,126 +493,15 @@ The Python client library provides a parameter binding api for inserting data. S
|
|||
<Tabs>
|
||||
<TabItem value="native" label="native connection">
|
||||
|
||||
##### Create Stmt
|
||||
|
||||
Call the `statement` method in `Connection` to create the `stmt` for parameter binding.
|
||||
|
||||
```
|
||||
import taos
|
||||
|
||||
conn = taos.connect()
|
||||
stmt = conn.statement("insert into log values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)")
|
||||
```
|
||||
|
||||
##### parameter binding
|
||||
|
||||
Call the `new_multi_binds` function to create the parameter list for parameter bindings.
|
||||
|
||||
```
|
||||
params = new_multi_binds(16)
|
||||
params[0].timestamp((1626861392589, 1626861392590, 1626861392591))
|
||||
params[1].bool((True, None, False))
|
||||
params[2].tinyint([-128, -128, None]) # -128 is tinyint null
|
||||
params[3].tinyint([0, 127, None])
|
||||
params[4].smallint([3, None, 2])
|
||||
params[5].int([3, 4, None])
|
||||
params[6].bigint([3, 4, None])
|
||||
params[7].tinyint_unsigned([3, 4, None])
|
||||
params[8].smallint_unsigned([3, 4, None])
|
||||
params[9].int_unsigned([3, 4, None])
|
||||
params[10].bigint_unsigned([3, 4, None])
|
||||
params[11].float([3, None, 1])
|
||||
params[12].double([3, None, 1.2])
|
||||
params[13].binary(["abc", "dddafadfadfadfadfa", None])
|
||||
params[14].nchar(["涛思数据", None, "a long string with 中文字符"])
|
||||
params[15].timestamp([None, None, 1626861392591])
|
||||
```
|
||||
|
||||
Call the `bind_param` (for a single row) method or the `bind_param_batch` (for multiple rows) method to set the values.
|
||||
|
||||
```
|
||||
stmt.bind_param_batch(params)
|
||||
```
|
||||
|
||||
##### execute sql
|
||||
|
||||
Call `execute` method to execute sql.
|
||||
|
||||
```
|
||||
stmt.execute()
|
||||
```
|
||||
|
||||
##### Close Stmt
|
||||
|
||||
```
|
||||
stmt.close()
|
||||
```
|
||||
|
||||
##### Example
|
||||
|
||||
```python
|
||||
{{#include docs/examples/python/stmt_example.py}}
|
||||
{{#include docs/examples/python/stmt_native.py:stmt}}
|
||||
```
|
||||
</TabItem>
|
||||
|
||||
<TabItem value="websocket" label="WebSocket connection">
|
||||
|
||||
##### Create Stmt
|
||||
|
||||
Call the `statement` method in `Connection` to create the `stmt` for parameter binding.
|
||||
|
||||
```
|
||||
import taosws
|
||||
|
||||
conn = taosws.connect('taosws://localhost:6041/test')
|
||||
stmt = conn.statement()
|
||||
```
|
||||
|
||||
##### Prepare sql
|
||||
|
||||
Call `prepare` method in stmt to prepare sql.
|
||||
|
||||
```
|
||||
stmt.prepare("insert into t1 values (?, ?, ?, ?)")
|
||||
```
|
||||
|
||||
##### parameter binding
|
||||
|
||||
Call the `bind_param` method to bind parameters.
|
||||
|
||||
```
|
||||
stmt.bind_param([
|
||||
taosws.millis_timestamps_to_column([1686844800000, 1686844801000, 1686844802000, 1686844803000]),
|
||||
taosws.ints_to_column([1, 2, 3, 4]),
|
||||
taosws.floats_to_column([1.1, 2.2, 3.3, 4.4]),
|
||||
taosws.varchar_to_column(['a', 'b', 'c', 'd']),
|
||||
])
|
||||
```
|
||||
|
||||
Call the `add_batch` method to add parameters to the batch.
|
||||
|
||||
```
|
||||
stmt.add_batch()
|
||||
```
|
||||
|
||||
##### execute sql
|
||||
|
||||
Call `execute` method to execute sql.
|
||||
|
||||
```
|
||||
stmt.execute()
|
||||
```
|
||||
|
||||
##### Close Stmt
|
||||
|
||||
```
|
||||
stmt.close()
|
||||
```
|
||||
|
||||
##### Example
|
||||
|
||||
```python
|
||||
{{#include docs/examples/python/stmt_websocket_example.py}}
|
||||
{{#include docs/examples/python/stmt_ws.py:stmt}}
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
@ -758,46 +511,18 @@ stmt.close()
|
|||
Client library support schemaless insert.
|
||||
|
||||
<Tabs defaultValue="list">
|
||||
<TabItem value="list" label="List Insert">
|
||||
|
||||
##### Simple insert
|
||||
<TabItem value="list" label="native connection">
|
||||
|
||||
```python
|
||||
{{#include docs/examples/python/schemaless_insert.py}}
|
||||
```
|
||||
|
||||
##### Insert with ttl argument
|
||||
|
||||
```python
|
||||
{{#include docs/examples/python/schemaless_insert_ttl.py}}
|
||||
```
|
||||
|
||||
##### Insert with req_id argument
|
||||
|
||||
```python
|
||||
{{#include docs/examples/python/schemaless_insert_req_id.py}}
|
||||
{{#include docs/examples/python/schemaless_native.py}}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
|
||||
<TabItem value="raw" label="Raw Insert">
|
||||
|
||||
##### Simple insert
|
||||
<TabItem value="raw" label="WebSocket connection">
|
||||
|
||||
```python
|
||||
{{#include docs/examples/python/schemaless_insert_raw.py}}
|
||||
```
|
||||
|
||||
##### Insert with ttl argument
|
||||
|
||||
```python
|
||||
{{#include docs/examples/python/schemaless_insert_raw_ttl.py}}
|
||||
```
|
||||
|
||||
##### Insert with req_id argument
|
||||
|
||||
```python
|
||||
{{#include docs/examples/python/schemaless_insert_raw_req_id.py}}
|
||||
{{#include docs/examples/python/schemaless_ws.py}}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
|
@ -808,11 +533,12 @@ Client library support schemaless insert.
|
|||
There is a optional parameter called `req_id` in `schemaless_insert` and `schemaless_insert_raw` method. This reqId can be used to request link tracing.
|
||||
|
||||
```python
|
||||
{{#include docs/examples/python/schemaless_insert_req_id.py}}
|
||||
```
|
||||
|
||||
```python
|
||||
{{#include docs/examples/python/schemaless_insert_raw_req_id.py}}
|
||||
conn.schemaless_insert(
|
||||
lines=lineDemo,
|
||||
protocol=taos.SmlProtocol.LINE_PROTOCOL,
|
||||
precision=taos.SmlPrecision.NANO_SECONDS,
|
||||
req_id=1,
|
||||
)
|
||||
```
|
||||
|
||||
### Data Subscription
|
||||
|
@ -821,194 +547,56 @@ Client library support data subscription. For more information about subscroptio
|
|||
|
||||
#### Create a Topic
|
||||
|
||||
To create topic, please refer to [Data Subscription](../../develop/tmq/#create-a-topic).
|
||||
```python
|
||||
{{#include docs/examples/python/tmq_native.py:create_topic}}
|
||||
```
|
||||
|
||||
#### Create a Consumer
|
||||
|
||||
<Tabs defaultValue="native">
|
||||
|
||||
<TabItem value="native" label="native connection">
|
||||
|
||||
The consumer in the client library contains the subscription api. The syntax for creating a consumer is consumer = Consumer(configs). For more subscription api parameters, please refer to [Data Subscription](../../develop/tmq/#create-a-consumer).
|
||||
|
||||
```python
|
||||
from taos.tmq import Consumer
|
||||
|
||||
consumer = Consumer({"group.id": "local", "td.connect.ip": "127.0.0.1"})
|
||||
{{#include docs/examples/python/tmq_native.py:create_consumer}}
|
||||
```
|
||||
</TabItem>
|
||||
|
||||
<TabItem value="websocket" label="WebSocket connection">
|
||||
|
||||
In addition to native connections, the client library also supports subscriptions via websockets.
|
||||
|
||||
The syntax for creating a consumer is "consumer = Consumer(conf=configs)". You need to specify that the `td.connect.websocket.scheme` parameter is set to "ws" in the configuration. For more subscription api parameters, please refer to [Data Subscription](../../develop/tmq/#create-a-consumer).
|
||||
|
||||
```python
|
||||
import taosws
|
||||
|
||||
consumer = taosws.Consumer(conf={"group.id": "local", "td.connect.websocket.scheme": "ws"})
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
#### Subscribe to a Topic
|
||||
|
||||
<Tabs defaultValue="native">
|
||||
|
||||
<TabItem value="native" label="native connection">
|
||||
|
||||
The `subscribe` function is used to subscribe to a list of topics.
|
||||
|
||||
```python
|
||||
consumer.subscribe(['topic1', 'topic2'])
|
||||
{{#include docs/examples/python/tmq_native.py:subscribe}}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="websocket" label="WebSocket connection">
|
||||
|
||||
The `subscribe` function is used to subscribe to a list of topics.
|
||||
|
||||
```python
|
||||
consumer.subscribe(['topic1', 'topic2'])
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
#### Consume messages
|
||||
|
||||
<Tabs defaultValue="native">
|
||||
|
||||
<TabItem value="native" label="native connection">
|
||||
|
||||
The `poll` function is used to consume data in tmq. The parameter of the `poll` function is a value of type float representing the timeout in seconds. It returns a `Message` before timing out, or `None` on timing out. You have to handle error messages in response data.
|
||||
|
||||
```python
|
||||
while True:
|
||||
message = consumer.poll(1)
|
||||
if not message:
|
||||
continue
|
||||
err = message.error()
|
||||
if err is not None:
|
||||
raise err
|
||||
val = message.value()
|
||||
|
||||
for block in val:
|
||||
print(block.fetchall())
|
||||
{{#include docs/examples/python/tmq_native.py:consume}}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="websocket" label="WebSocket connection">
|
||||
|
||||
The `poll` function is used to consume data in tmq. The parameter of the `poll` function is a value of type float representing the timeout in seconds. It returns a `Message` before timing out, or `None` on timing out.
|
||||
|
||||
```python
|
||||
while True:
|
||||
message = consumer.poll(1)
|
||||
if not message:
|
||||
continue
|
||||
|
||||
for block in message:
|
||||
for row in block:
|
||||
print(row)
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
#### Assignment subscription Offset
|
||||
|
||||
<Tabs defaultValue="native">
|
||||
|
||||
<TabItem value="native" label="native connection">
|
||||
|
||||
The `assignment` function is used to get the assignment of the topic.
|
||||
|
||||
```python
|
||||
assignments = consumer.assignment()
|
||||
{{#include docs/examples/python/tmq_native.py:assignment}}
|
||||
```
|
||||
|
||||
The `seek` function is used to reset the assignment of the topic.
|
||||
|
||||
```python
|
||||
tp = TopicPartition(topic='topic1', partition=0, offset=0)
|
||||
consumer.seek(tp)
|
||||
{{#include docs/examples/python/tmq_native.py:consume}}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="websocket" label="WebSocket connection">
|
||||
|
||||
The `assignment` function is used to get the assignment of the topic.
|
||||
|
||||
```python
|
||||
assignments = consumer.assignment()
|
||||
```
|
||||
|
||||
The `seek` function is used to reset the assignment of the topic.
|
||||
|
||||
```python
|
||||
consumer.seek(topic='topic1', partition=0, offset=0)
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
#### Close subscriptions
|
||||
|
||||
<Tabs defaultValue="native">
|
||||
|
||||
<TabItem value="native" label="native connection">
|
||||
|
||||
You should unsubscribe to the topics and close the consumer after consuming.
|
||||
|
||||
```python
|
||||
consumer.unsubscribe()
|
||||
consumer.close()
|
||||
{{#include docs/examples/python/tmq_native.py:unsubscribe}}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="websocket" label="WebSocket connection">
|
||||
|
||||
You should unsubscribe to the topics and close the consumer after consuming.
|
||||
|
||||
```python
|
||||
consumer.unsubscribe()
|
||||
consumer.close()
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
#### Full Sample Code
|
||||
|
||||
<Tabs defaultValue="native">
|
||||
|
||||
<TabItem value="native" label="native connection">
|
||||
|
||||
```python
|
||||
{{#include docs/examples/python/tmq_example.py}}
|
||||
{{#include docs/examples/python/tmq_native.py}}
|
||||
```
|
||||
|
||||
```python
|
||||
{{#include docs/examples/python/tmq_assignment_example.py:taos_get_assignment_and_seek_demo}}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="websocket" label="WebSocket connection">
|
||||
|
||||
```python
|
||||
{{#include docs/examples/python/tmq_websocket_example.py}}
|
||||
```
|
||||
|
||||
```python
|
||||
{{#include docs/examples/python/tmq_websocket_assgnment_example.py:taosws_get_assignment_and_seek_demo}}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
### Other sample programs
|
||||
|
||||
| Example program links | Example program content |
|
||||
|
|
|
@ -7,35 +7,30 @@ toc_max_heading_level: 4
|
|||
|
||||
import Tabs from "@theme/Tabs";
|
||||
import TabItem from "@theme/TabItem";
|
||||
import RequestId from "./_request_id.mdx";
|
||||
|
||||
import Preparition from "./_preparation.mdx";
|
||||
import NodeInsert from "../07-develop/03-insert-data/_js_sql.mdx";
|
||||
import NodeInfluxLine from "../07-develop/03-insert-data/_js_line.mdx";
|
||||
import NodeOpenTSDBTelnet from "../07-develop/03-insert-data/_js_opts_telnet.mdx";
|
||||
import NodeOpenTSDBJson from "../07-develop/03-insert-data/_js_opts_json.mdx";
|
||||
import NodeQuery from "../07-develop/04-query-data/_js.mdx";
|
||||
`@tdengine/websocket` is the official Node.js client library for TDengine. Node.js developers can develop applications to access the TDengine instance data.
|
||||
|
||||
`@tdengine/client` and `@tdengine/rest` are the official Node.js client libraries. Node.js developers can develop applications to access TDengine instance data. Note: The client libraries for TDengine 3.0 are different than those for TDengine 2.x. The new client libraries do not support TDengine 2.x.
|
||||
The source code for the Node.js client library is hosted on [GitHub](https://github.com/taosdata/taos-connector-node/tree/main).
|
||||
|
||||
`@tdengine/client` is **native connection**, which connects to TDengine instances natively through the TDengine client driver (taosc), supporting data writing, querying, subscriptions, schemaless writing, and bind interface. `@tdengine/rest` is the **REST connection**, which connects to TDengine instances via the REST interface provided by taosAdapter. The REST client library can run on any platform, but performance is slightly degraded, and the interface implements a somewhat different set of functional features than the native interface.
|
||||
## Connection types
|
||||
|
||||
The source code for the Node.js client libraries is located on [GitHub](https://github.com/taosdata/taos-connector-node/tree/3.0).
|
||||
Node.js connector supports only websocket connection through taosAdapter.
|
||||
|
||||
For a detailed introduction of the connection types, please refer to: [Establish Connection](../../develop/connect/#establish-connection)
|
||||
|
||||
## Supported platforms
|
||||
|
||||
The platforms supported by the native client library are the same as those supported by the TDengine client driver.
|
||||
The REST client library supports all platforms that can run Node.js.
|
||||
Node.js client library needs to be run with Node.js 14 or higher version.
|
||||
|
||||
## Version support
|
||||
## Recent update logs
|
||||
|
||||
Please refer to [version support list](../#version-support)
|
||||
| Node.js connector version | major changes | TDengine 版本 |
|
||||
| :-----------------------: | :------------------: | :----------------:|
|
||||
| 3.1.0 | new version, supports websocket | 3.2.0.0 or later |
|
||||
|
||||
## Supported features
|
||||
|
||||
|
||||
<Tabs defaultValue="native">
|
||||
<TabItem value="native" label="Native connection">
|
||||
|
||||
1. Connection Management
|
||||
2. General Query
|
||||
3. Continuous Query
|
||||
|
@ -43,294 +38,300 @@ Please refer to [version support list](../#version-support)
|
|||
5. Subscription
|
||||
6. Schemaless
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="rest" label="REST connection">
|
||||
## Handling exceptions
|
||||
|
||||
1. Connection Management
|
||||
2. General Query
|
||||
3. Continuous Query
|
||||
After an error is reported, the error message and error code can be obtained through try catch. The Node.js client library error code is between 100 and 110, while the other error codes are for the TDengine function module.
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
Please refer to the table below for error code, error description and corresponding suggestions.
|
||||
|
||||
| Error Code | Description | Suggested Actions |
|
||||
| ---------- | -------------------------------------------------------------| -------------------------------------------------------------------------------------------------- |
|
||||
| 100 | invalid variables | The parameter is invalid. Check the interface specification and adjust the parameter type and size.|
|
||||
| 101 | invalid url | URL error, please check if the url is correct. |
|
||||
| 102 | received server data but did not find a callback for processing | Client waiting timeout, please check network and TaosAdapter status. |
|
||||
| 103 | invalid message type | Please check if the client version and server version match. |
|
||||
| 104 | connection creation failed | Connection creation failed. Please check the network and TaosAdapter status. |
|
||||
| 105 | websocket request timeout | Increase the execution time by adding the messageWaitTimeout parameter, or check the connection to the TaosAdapter.|
|
||||
| 106 | authentication fail | Authentication failed, please check if the username and password are correct. |
|
||||
| 107 | unknown sql type in tdengine | Check the data type supported by TDengine. |
|
||||
| 108 | connection has been closed | The connection has been closed, check the connection status, or recreate the connection to execute the relevant instructions. |
|
||||
| 109 | fetch block data parse fail | Please check if the client version and server version match. |
|
||||
| 110 | websocket connection has reached its maximum limit | Please check if the connection has been closed after use |
|
||||
|
||||
## Data Type Mapping
|
||||
|
||||
The table below despicts the mapping between TDengine data type and Node.js data type.
|
||||
|
||||
| TDengine Data Type | Node.js Data Type|
|
||||
|-------------------|-------------|
|
||||
| TIMESTAMP | bigint |
|
||||
| TINYINT | number |
|
||||
| SMALLINT | number |
|
||||
| INT | number |
|
||||
| BIGINT | bigint |
|
||||
| TINYINT UNSIGNED | number |
|
||||
| SMALLINT UNSIGNED | number |
|
||||
| INT UNSIGNED | number |
|
||||
| BIGINT UNSIGNED | bigint |
|
||||
| FLOAT | number |
|
||||
| DOUBLE | number |
|
||||
| BOOL | boolean |
|
||||
| BINARY | string |
|
||||
| NCHAR | string |
|
||||
| JSON | string |
|
||||
| VARBINARY | ArrayBuffer |
|
||||
| GEOMETRY | ArrayBuffer |
|
||||
|
||||
**Note**: Only TAG supports JSON types
|
||||
|
||||
## Installation Steps
|
||||
|
||||
### Pre-installation preparation
|
||||
|
||||
- Install the Node.js development environment
|
||||
- If you are using the REST client library, skip this step. However, if you use the native client library, please install the TDengine client driver. Please refer to [Install Client Driver](../#install-client-driver) for more details. We use [node-gyp](https://github.com/nodejs/node-gyp) to interact with TDengine instances and also need to install some dependencies mentioned below depending on the specific OS.
|
||||
- Install the Node.js development environment, using version 14 or above. Download link: https://nodejs.org/en/download/
|
||||
|
||||
<Tabs defaultValue="Linux">
|
||||
<TabItem value="Linux" label="Linux system installation dependencies">
|
||||
|
||||
- `python` (recommended for `v2.7` , `v3.x.x` currently not supported)
|
||||
- `@tdengine/client` 3.0.0 supports Node.js LTS v10.9.0 or later and Node.js LTS v12.8.0 or later. Older versions may be incompatible.
|
||||
- `make`
|
||||
- C compiler, [GCC](https://gcc.gnu.org) v4.8.5 or later.
|
||||
|
||||
</TabItem>
|
||||
|
||||
<TabItem value="macOS" label="macOS installation dependencies">
|
||||
|
||||
- `python` (recommended for `v2.7` , `v3.x.x` currently not supported)
|
||||
- `@tdengine/client` 3.0.0 currently supports Node.js from v12.22.12, but only later versions of v12. Other versions may be incompatible.
|
||||
- `make`
|
||||
- C compiler, [GCC](https://gcc.gnu.org) v4.8.5 or later.
|
||||
|
||||
</TabItem>
|
||||
|
||||
<TabItem value="Windows" label="Windows system installation dependencies">
|
||||
|
||||
- Installation method 1
|
||||
|
||||
Use Microsoft's [windows-build-tools](https://github.com/felixrieseberg/windows-build-tools) to execute `npm install --global --production` from the `cmd` command-line interface to install all the necessary tools.
|
||||
|
||||
- Installation method 2
|
||||
|
||||
Manually install the following tools.
|
||||
|
||||
- Install Visual Studio related: [Visual Studio Build Tools](https://visualstudio.microsoft.com/thank-you-downloading-visual-studio/?sku=BuildTools) or [Visual Studio 2017 Community](https://visualstudio.microsoft.com/pl/thank-you-downloading-visual-studio/?sku=Community)
|
||||
- Install [Python](https://www.python.org/downloads/) 2.7 (`v3.x.x` is not supported) and execute `npm config set python python2.7`.
|
||||
- Go to the `cmd` command-line interface, `npm config set msvs_version 2017`
|
||||
|
||||
Refer to Microsoft's Node.js User Manual [Microsoft's Node.js Guidelines for Windows](https://github.com/Microsoft/nodejs-guidelines/blob/master/windows-environment.md#compiling-native-addon-modules).
|
||||
|
||||
If using ARM64 Node.js on Windows 10 ARM, you must add "Visual C++ compilers and libraries for ARM64" and "Visual C++ ATL for ARM64".
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
### Install via npm
|
||||
|
||||
<Tabs defaultValue="install_rest">
|
||||
<TabItem value="install_native" label="Install native clieny library">
|
||||
### Install Node.js client library via npm
|
||||
|
||||
```bash
|
||||
npm install @tdengine/client
|
||||
npm install @tdengine/websocket
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="install_rest" label="Install REST client library">
|
||||
|
||||
```bash
|
||||
npm install @tdengine/rest
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
### Verify
|
||||
|
||||
<Tabs defaultValue="native">
|
||||
<TabItem value="native" label="Native client library">
|
||||
|
||||
After installing the TDengine client, use the `nodejsChecker.js` program to verify that the current environment supports Node.js access to TDengine.
|
||||
|
||||
Verification in details:
|
||||
|
||||
- Create an installation test folder such as `~/tdengine-test`. Download the [nodejsChecker.js source code](https://github.com/taosdata/taos-connector-node/blob/3.0/nodejs/examples/nodejsChecker.js) to your local machine.
|
||||
- Create an installation test folder such as `~/tdengine-test`. Download the [nodejsChecker.js](https://github.com/taosdata/TDengine/tree/main/docs/examples/node/websocketexample/nodejsChecker.js) to your local machine.
|
||||
|
||||
- Execute the following command from the command-line.
|
||||
|
||||
```bash
|
||||
npm init -y
|
||||
npm install @tdengine/client
|
||||
node nodejsChecker.js host=localhost
|
||||
npm init -y
|
||||
npm install @tdengine/websocket
|
||||
node nodejsChecker.js host=localhost
|
||||
```
|
||||
|
||||
- After executing the above steps, the command-line will output the result of `nodejsChecker.js` connecting to the TDengine instance and performing a simple insert and query.
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="rest" label="REST client library">
|
||||
|
||||
After installing the TDengine client, use the `restChecker.js` program to verify that the current environment supports Node.js access to TDengine.
|
||||
|
||||
Verification in details:
|
||||
|
||||
- Create an installation test folder such as `~/tdengine-test`. Download the [restChecker.js source code](https://github.com/taosdata/TDengine/tree/3.0/docs/examples/node/restexample/restChecker.js) to your local.
|
||||
|
||||
- Execute the following command from the command-line.
|
||||
|
||||
```bash
|
||||
npm init -y
|
||||
npm install @tdengine/rest
|
||||
node restChecker.js
|
||||
```
|
||||
|
||||
- After executing the above steps, the command-line will output the result of `restChecker.js` connecting to the TDengine instance and performing a simple insert and query.
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## Establishing a connection
|
||||
|
||||
Please choose to use one of the client libraries.
|
||||
Install and import the `@tdengine/websocket` package.
|
||||
|
||||
<Tabs defaultValue="rest">
|
||||
<TabItem value="native" label="native connection">
|
||||
|
||||
Install and import the `@tdengine/client` package.
|
||||
**Note**: After using the Node.js client library, it is necessary to call taos.destroy() Release connector resources.
|
||||
|
||||
```javascript
|
||||
//A cursor also needs to be initialized in order to interact with TDengine from Node.js.
|
||||
const taos = require("@tdengine/client");
|
||||
var conn = taos.connect({
|
||||
host: "127.0.0.1",
|
||||
user: "root",
|
||||
password: "taosdata",
|
||||
config: "/etc/taos",
|
||||
port: 0,
|
||||
});
|
||||
var cursor = conn.cursor(); // Initializing a new cursor
|
||||
const taos = require("@tdengine/websocket");
|
||||
|
||||
//Close a connection
|
||||
conn.close();
|
||||
//database operations......
|
||||
|
||||
taos.destroy();
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="rest" label="REST connection">
|
||||
|
||||
Install and import the `@tdengine/rest` package.
|
||||
|
||||
```javascript
|
||||
//A cursor also needs to be initialized in order to interact with TDengine from Node.js.
|
||||
import { options, connect } from "@tdengine/rest";
|
||||
options.path = "/rest/sql";
|
||||
// set host
|
||||
options.host = "localhost";
|
||||
// set other options like user/passwd
|
||||
|
||||
let conn = connect(options);
|
||||
let cursor = conn.cursor();
|
||||
WSConfig configures the Websocket parameters as follows:
|
||||
getToken(): string | undefined | null;
|
||||
setToken(token: string): void;
|
||||
getUser(): string | undefined | null;
|
||||
setUser(user: string): void;
|
||||
getPwd(): string | undefined | null;
|
||||
setPwd(pws: string): void;
|
||||
getDb(): string | undefined | null;
|
||||
setDb(db: string): void;
|
||||
getUrl(): string;
|
||||
setUrl(url: string): void;
|
||||
setTimeOut(ms: number): void;
|
||||
getTimeOut(): number | undefined | null;
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
```javascript
|
||||
{{#include docs/examples/node/websocketexample/sql_example.js:createConnect}}
|
||||
```
|
||||
|
||||
## Usage examples
|
||||
|
||||
### Write data
|
||||
### Create database and tables
|
||||
|
||||
#### SQL Write
|
||||
|
||||
<Tabs defaultValue="native">
|
||||
<TabItem value="native" label="native connection">
|
||||
|
||||
<NodeInsert />
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="rest" label="REST connection">
|
||||
|
||||
```js
|
||||
{{#include docs/examples/node/restexample/insert_example.js}}
|
||||
```javascript
|
||||
{{#include docs/examples/node/websocketexample/sql_example.js:create_db_and_table}}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
**Note**: If you do not use `USE power` to specify the database, all subsequent operations on the table need to add the database name as a prefix, such as power.meters.
|
||||
|
||||
#### InfluxDB line protocol write
|
||||
### Insert data
|
||||
|
||||
<Tabs defaultValue="native">
|
||||
<TabItem value="native" label="native connection">
|
||||
```javascript
|
||||
{{#include docs/examples/node/websocketexample/sql_example.js:insertData}}
|
||||
```
|
||||
|
||||
<NodeInfluxLine />
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
#### OpenTSDB Telnet line protocol write
|
||||
|
||||
<Tabs defaultValue="native">
|
||||
<TabItem value="native" label="native connection">
|
||||
|
||||
<NodeOpenTSDBTelnet />
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
#### OpenTSDB JSON line protocol write
|
||||
|
||||
<Tabs defaultValue="native">
|
||||
<TabItem value="native" label="native connection">
|
||||
|
||||
<NodeOpenTSDBJson />
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
> NOW is an internal function. The default is the current time of the client's computer.
|
||||
> `NOW + 1s` represents the current time of the client plus 1 second, followed by the number representing the unit of time: a (milliseconds), s (seconds), m (minutes), h (hours), d (days), w (weeks), n (months), y (years).
|
||||
|
||||
### Querying data
|
||||
|
||||
<Tabs defaultValue="native">
|
||||
<TabItem value="native" label="native connection">
|
||||
|
||||
<NodeQuery />
|
||||
|
||||
</TabItem>
|
||||
|
||||
<TabItem value="rest" label="REST connection">
|
||||
|
||||
```js
|
||||
{{#include docs/examples/node/restexample/query_example.js}}
|
||||
```javascript
|
||||
{{#include docs/examples/node/websocketexample/sql_example.js:queryData}}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
> Discovered data structure
|
||||
|
||||
```javascript
|
||||
wsRow:meta:=> [
|
||||
{ name: 'ts', type: 'TIMESTAMP', length: 8 },
|
||||
{ name: 'current', type: 'FLOAT', length: 4 },
|
||||
{ name: 'voltage', type: 'INT', length: 4 },
|
||||
{ name: 'phase', type: 'FLOAT', length: 4 },
|
||||
{ name: 'location', type: 'VARCHAR', length: 64},
|
||||
{ name: 'groupid', type: 'INT', length: 4 }
|
||||
]
|
||||
wsRow:data:=> [
|
||||
[ 1714013737536n, 12.3, 221, 0.31, 'California.SanFrancisco', 3 ]
|
||||
]
|
||||
```
|
||||
|
||||
### Execute SQL with reqId
|
||||
|
||||
<RequestId />
|
||||
|
||||
```javascript
|
||||
{{#include docs/examples/node/websocketexample/sql_example.js:sqlWithReqid}}
|
||||
```
|
||||
|
||||
### Writing data via parameter binding
|
||||
|
||||
The Node.js client library provides a parameter binding api for inserting data. Similar to most databases, TDengine currently only supports the question mark `?` to indicate the parameters to be bound.
|
||||
|
||||
**Note**: Do not use `db.?` in prepareStatement when specify the database with the table name, should directly use `?`, then specify the database in setTableName, for example: `prepareStatement.setTableName("db.t1")`.
|
||||
|
||||
Sample Code:
|
||||
|
||||
```javascript
|
||||
{{#include docs/examples/node/websocketexample/stmt_example.js}}
|
||||
```
|
||||
|
||||
The methods to set TAGS values or VALUES columns:
|
||||
|
||||
```javascript
|
||||
setBoolean(params: any[]): void;
|
||||
setTinyInt(params: any[]): void;
|
||||
setUTinyInt(params: any[]): void;
|
||||
setSmallInt(params: any[]): void;
|
||||
setUSmallInt(params: any[]): void;
|
||||
setInt(params: any[]): void;
|
||||
setUInt(params: any[]): void;
|
||||
setBigint(params: any[]): void;
|
||||
setUBigint(params: any[]): void;
|
||||
setFloat(params: any[]): void;
|
||||
setDouble(params: any[]): void;
|
||||
setVarchar(params: any[]): void;
|
||||
setBinary(params: any[]): void;
|
||||
setNchar(params: any[]): void;
|
||||
setJson(params: any[]): void;
|
||||
setVarBinary(params: any[]): void;
|
||||
setGeometry(params: any[]): void;
|
||||
setTimestamp(params: any[]): void;
|
||||
```
|
||||
|
||||
**Note**: Only TAG supports JSON types
|
||||
|
||||
### Schemaless Writing
|
||||
|
||||
TDengine supports schemaless writing. It is compatible with InfluxDB's Line Protocol, OpenTSDB's telnet line protocol, and OpenTSDB's JSON format protocol. For more information, see [Schemaless Writing](../../reference/schemaless/).
|
||||
|
||||
```javascript
|
||||
{{#include docs/examples/node/websocketexample/line_example.js}}
|
||||
```
|
||||
|
||||
### Schemaless with reqId
|
||||
|
||||
This reqId can be used to request link tracing.
|
||||
|
||||
```javascript
|
||||
await wsSchemaless.schemalessInsert([influxdbData], SchemalessProto.InfluxDBLineProtocol, Precision.NANO_SECONDS, ttl, reqId);
|
||||
await wsSchemaless.schemalessInsert([telnetData], SchemalessProto.OpenTSDBTelnetLineProtocol, Precision.NANO_SECONDS, ttl, reqId);
|
||||
await wsSchemaless.schemalessInsert([jsonData], SchemalessProto.OpenTSDBJsonFormatProtocol, Precision.NANO_SECONDS, ttl, reqId);
|
||||
```
|
||||
|
||||
### Data Subscription
|
||||
|
||||
The TDengine Node.js client library supports subscription functionality with the following application API.
|
||||
|
||||
#### Create a Topic
|
||||
|
||||
```javascript
|
||||
{{#include docs/examples/node/websocketexample/tmq_example.js:create_topic}}
|
||||
```
|
||||
|
||||
#### Create a Consumer
|
||||
|
||||
```javascript
|
||||
{{#include docs/examples/node/websocketexample/tmq_example.js:create_consumer}}
|
||||
```
|
||||
|
||||
**Parameter Description**
|
||||
|
||||
- taos.TMQConstants.CONNECT_USER: username.
|
||||
- taos.TMQConstants.CONNECT_PASS: password.
|
||||
- taos.TMQConstants.GROUP_ID: Specifies the group that the consumer is in.
|
||||
- taos.TMQConstants.CLIENT_ID: client id.
|
||||
- taos.TMQConstants.WS_URL: The URL address of TaosAdapter.
|
||||
- taos.TMQConstants.AUTO_OFFSET_RESET: When offset does not exist, where to start consumption, the optional value is earliest or latest, the default is latest.
|
||||
- taos.TMQConstants.ENABLE_AUTO_COMMIT: Specifies whether to commit automatically.
|
||||
- taos.TMQConstants.AUTO_COMMIT_INTERVAL_MS: Automatic submission interval, the default value is 5000 ms.
|
||||
- taos.TMQConstants.CONNECT_MESSAGE_TIMEOUT: socket timeout in milliseconds, the default value is 10000 ms. It only takes effect when using WebSocket type.
|
||||
|
||||
For more information, see [Consumer Parameters](../../develop/tmq). Note that the default value of auto.offset.reset in data subscription on the TDengine server has changed since version 3.2.0.0.
|
||||
|
||||
#### Subscribe to consume data
|
||||
|
||||
```javascript
|
||||
{{#include docs/examples/node/websocketexample/tmq_example.js:subscribe}}
|
||||
```
|
||||
|
||||
#### Assignment subscription Offset
|
||||
|
||||
```javascript
|
||||
{{#include docs/examples/node/websocketexample/tmq_example.js:assignment}}
|
||||
```
|
||||
|
||||
#### Close subscriptions
|
||||
|
||||
```java
|
||||
// Unsubscribe
|
||||
consumer.unsubscribe();
|
||||
// Close consumer
|
||||
consumer.close()
|
||||
// free connector resource
|
||||
taos.destroy();
|
||||
```
|
||||
|
||||
For more information, see [Data Subscription](../../develop/tmq).
|
||||
|
||||
#### Full Sample Code
|
||||
|
||||
```javascript
|
||||
{{#include docs/examples/node/websocketexample/tmq_example.js}}
|
||||
```
|
||||
|
||||
## More sample programs
|
||||
|
||||
| Sample Programs | Sample Program Description |
|
||||
| --------------------------------------------------------------------------------------------------------------------------------- --------- | -------------------------------------- |
|
||||
| [basicUse](https://github.com/taosdata/taos-connector-node/blob/3.0/nodejs/examples/queryExample.js) | Basic operations such as establishing connections and running SQl commands. |
|
||||
| [stmtBindBatch](https://github.com/taosdata/taos-connector-node/blob/3.0/nodejs/examples/bindParamBatch.js) | Binding multi-line parameter insertion. | |
|
||||
| [stmtBindSingleParamBatch](https://github.com/taosdata/taos-connector-node/blob/3.0/nodejs/examples/bindSingleParamBatch.js) | Columnar binding parameter insertion |
|
||||
| [stmtQuery](https://github.com/taosdata/taos-connector-node/blob/3.0/nodejs/examples/stmtQuery.js) | Binding parameter query |
|
||||
| [schemless insert](https://github.com/taosdata/taos-connector-node/blob/3.0/nodejs/examples/schemaless.js) | Schemaless insert |
|
||||
| [TMQ](https://github.com/taosdata/taos-connector-node/blob/3.0/nodejs/examples/tmq.js) | Using data subscription |
|
||||
| [asyncQuery](https://github.com/taosdata/taos-connector-node/blob/3.0/nodejs/examples/asyncQueryExample.js) | Using asynchronous queries |
|
||||
| [REST](https://github.com/taosdata/taos-connector-node/blob/3.0/typescript-rest/example/example.ts) | Using TypeScript with the REST client library |
|
||||
| ---------------------------------------------------------------------------------------------------------------------------------| -------------------------------------- |
|
||||
| [sql_example](https://github.com/taosdata/TDengine/tree/main/docs/examples/node/websocketexample/sql_example.js) | Basic operations such as establishing connections and running SQl commands.|
|
||||
| [stmt_example](https://github.com/taosdata/TDengine/tree/main/docs/examples/node/websocketexample/stmt_example.js) | Binding multi-line parameter insertion. | |
|
||||
| [line_example](https://github.com/taosdata/TDengine/tree/main/docs/examples/node/websocketexample/line_example.js) | Schemaless insert |
|
||||
| [telnet_line_example](https://github.com/taosdata/TDengine/tree/main/docs/examples/node/websocketexample/telnet_line_example.js) | OpenTSDB Telnet insert |
|
||||
| [json_line_example](https://github.com/taosdata/TDengine/tree/main/docs/examples/node/websocketexample/json_line_example.js) | OpenTSDB Json insert |
|
||||
| [tmq_example](https://github.com/taosdata/TDengine/tree/main/docs/examples/node/websocketexample/tmq_example.js) | Using data subscription |
|
||||
|
||||
## Usage limitations
|
||||
|
||||
`@tdengine/client` 3.0.0 supports Node.js LTS v12.8.0 to 12.9.1 and 10.9.0 to 10.20.0.
|
||||
|
||||
|
||||
|
||||
|
||||
- Node.js client library (`@tdengine/websocket`) supports Node.js 14 or higher.
|
||||
- It supports only WebSocket connection, so taosAdapter needs to be started in advance.
|
||||
- After using the connect, you need to call taos.destroy(); Release connector resources.
|
||||
|
||||
## Frequently Asked Questions
|
||||
|
||||
1. Using REST connections requires starting taosadapter.
|
||||
|
||||
```bash
|
||||
sudo systemctl start taosadapter
|
||||
```
|
||||
|
||||
2. Node.js versions
|
||||
|
||||
`@tdengine/client` supports Node.js v10.9.0 to 10.20.0 and 12.8.0 to 12.9.1.
|
||||
|
||||
3. "Unable to establish connection", "Unable to resolve FQDN"
|
||||
|
||||
Usually, the root cause is an incorrect FQDN configuration. You can refer to this section in the [FAQ](https://docs.tdengine.com/2.4/train-faq/faq/#2-how-to-handle-unable-to-establish-connection) to troubleshoot.
|
||||
|
||||
## Important update records
|
||||
|
||||
### Native client library
|
||||
|
||||
| package name | version | TDengine version | Description |
|
||||
|------------------|---------|---------------------|------------------------------------------------------------------|
|
||||
| @tdengine/client | 3.0.0 | 3.0.0 | Supports TDengine 3.0. Not compatible with TDengine 2.x. |
|
||||
| td2.0-connector | 2.0.12 | 2.4.x; 2.5.x; 2.6.x | Fixed cursor.close() bug. |
|
||||
| td2.0-connector | 2.0.11 | 2.4.x; 2.5.x; 2.6.x | Supports parameter binding, JSON tags and schemaless interface |
|
||||
| td2.0-connector | 2.0.10 | 2.4.x; 2.5.x; 2.6.x | Supports connection management, standard queries, connection queries, system information, and data subscription |
|
||||
### REST client library
|
||||
|
||||
| package name | version | TDengine version | Description |
|
||||
|----------------------|---------|---------------------|---------------------------------------------------------------------------|
|
||||
| @tdengine/rest | 3.0.0 | 3.0.0 | Supports TDengine 3.0. Not compatible with TDengine 2.x. |
|
||||
| td2.0-rest-connector | 1.0.7 | 2.4.x; 2.5.x; 2.6.x | Removed default port 6041 |
|
||||
| td2.0-rest-connector | 1.0.6 | 2.4.x; 2.5.x; 2.6.x | Fixed affectRows bug with create, insert, update, and alter. |
|
||||
| td2.0-rest-connector | 1.0.5 | 2.4.x; 2.5.x; 2.6.x | Support cloud token |
|
||||
| td2.0-rest-connector | 1.0.3 | 2.4.x; 2.5.x; 2.6.x | Supports connection management, standard queries, system information, error information, and continuous queries |
|
||||
1. "Unable to establish connection" or "Unable to resolve FQDN"
|
||||
|
||||
**Solution**: Usually, the root cause is an incorrect FQDN configuration. You can refer to this section in the [FAQ](../../train-faq/faq/#2-how-can-i-resolve-the-unable-to-establish-connection-error) to troubleshoot.
|
||||
|
|
|
@ -7,19 +7,23 @@ toc_max_heading_level: 4
|
|||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
import RequestId from "./_request_id.mdx";
|
||||
|
||||
`TDengine.Connector` is the C# language connector provided by TDengine. C# developers can use it to develop C# application software that accesses TDengine cluster data.
|
||||
|
||||
The `TDengine.Connector` connector supports establishing a connection with the TDengine running instance through the TDengine client driver (taosc), and provides functions such as data writing, query, data subscription, schemaless data writing, and parameter binding interface data writing. `TDengine.Connector` also supports WebSocket since v3.0.1, establishes WebSocket connection, and provides functions such as data writing, query, and parameter binding interface data writing.
|
||||
## Connection types
|
||||
|
||||
This article introduces how to install `TDengine.Connector` in a Linux or Windows environment, and connect to the TDengine cluster through `TDengine.Connector` to perform basic operations such as data writing and querying.
|
||||
`TDengine.Connector` provides 2 connection types.
|
||||
|
||||
* **Native connection**, which connects to TDengine instances natively through the TDengine client driver (taosc), supporting data writing, querying, subscriptions, schemaless writing, and bind interface.
|
||||
* **WebSocket connection** which is implemented through taosAdapter. The set of features implemented by the WebSocket connection differs slightly from those implemented by the native connection.(since v3.0.1)
|
||||
|
||||
For a detailed introduction of the connection types, please refer to: [Establish Connection](../../develop/connect/#establish-connection)
|
||||
|
||||
## Compatibility
|
||||
|
||||
:::warning
|
||||
* `TDengine.Connector` version 3.1.0 has been completely refactored and is no longer compatible with 3.0.2 and previous versions. For 3.0.2 documents, please refer to [nuget](https://www.nuget.org/packages/TDengine.Connector/3.0.2)
|
||||
* `TDengine.Connector` 3.x is not compatible with TDengine 2.x. If you need to use the C# connector in an environment running TDengine 2.x version, please use the 1.x version of TDengine.Connector.
|
||||
:::
|
||||
|
||||
The source code of `TDengine.Connector` is hosted on [GitHub](https://github.com/taosdata/taos-connector-dotnet/tree/3.0).
|
||||
|
||||
## Supported platforms
|
||||
|
||||
|
@ -31,9 +35,12 @@ TDengine no longer supports 32-bit Windows platforms.
|
|||
|
||||
## Version support
|
||||
|
||||
| **Connector version** | **TDengine version** |
|
||||
|-----------------------|----------------------|
|
||||
| 3.1.0 | 3.2.1.0/3.1.1.18 |
|
||||
| **Connector version** | **TDengine version** | **major features** |
|
||||
|-----------------------|----------------------|--------------------------------------|
|
||||
| 3.1.3 | 3.2.1.0/3.1.1.18 | support WebSocket reconnect |
|
||||
| 3.1.2 | 3.2.1.0/3.1.1.18 | fix schemaless result release |
|
||||
| 3.1.1 | 3.2.1.0/3.1.1.18 | support varbinary and geometry |
|
||||
| 3.1.0 | 3.2.1.0/3.1.1.18 | WebSocket uses native implementation |
|
||||
|
||||
## Handling exceptions
|
||||
|
||||
|
@ -58,6 +65,8 @@ TDengine no longer supports 32-bit Windows platforms.
|
|||
| BINARY | byte[] |
|
||||
| NCHAR | string (utf-8 encoding) |
|
||||
| JSON | byte[] |
|
||||
| VARBINARY | byte[] |
|
||||
| GEOMETRY | byte[] |
|
||||
|
||||
**Note**: JSON type is only supported in tag.
|
||||
|
||||
|
@ -67,7 +76,7 @@ TDengine no longer supports 32-bit Windows platforms.
|
|||
|
||||
* Install [.NET SDK](https://dotnet.microsoft.com/download)
|
||||
* [Nuget Client](https://docs.microsoft.com/en-us/nuget/install-nuget-client-tools) (optional installation)
|
||||
* Install the TDengine client driver. For specific steps, please refer to [Installing the client driver](../#install-client-driver)
|
||||
* Only for Native connections, you need to install the TDengine client driver. For specific steps, please refer to [Installing the client driver](../#install-client-driver)
|
||||
|
||||
### Install the connectors
|
||||
|
||||
|
@ -127,6 +136,12 @@ The parameters supported by `ConnectionStringBuilder` are as follows:
|
|||
* connTimeout: WebSocket connection timeout, only valid when the protocol is WebSocket, the default is 1 minute, use the `TimeSpan.Parse` method to parse the string into a `TimeSpan` object.
|
||||
* readTimeout: WebSocket read timeout, only valid when the protocol is WebSocket, the default is 5 minutes, use the `TimeSpan.Parse` method to parse the string into a `TimeSpan` object.
|
||||
* writeTimeout: WebSocket write timeout, only valid when the protocol is WebSocket, the default is 10 seconds, use the `TimeSpan.Parse` method to parse the string into a `TimeSpan` object.
|
||||
* enableCompression: Whether to enable WebSocket compression (effective for dotnet version 6 and above, connector version 3.1.1 and above). The default is false.
|
||||
* autoReconnect: Whether to enable WebSocket reconnect (connector version 3.1.3 and above). The default is false.
|
||||
> **Note**:Enabling automatic reconnection is only effective for simple SQL statement execution, schemaless writing, and data subscription. It is not effective for parameter binding. Automatic reconnection is only effective for the database specified by parameters when the connection is established, and it is not effective for the `use db` statement to switch databases later.
|
||||
|
||||
* reconnectRetryCount: The number of reconnection retries (connector version 3.1.3 and above). The default is 3.
|
||||
* reconnectIntervalMs: The interval between reconnection retries (connector version 3.1.3 and above). The default is 2000.
|
||||
|
||||
### Specify the URL and Properties to get the connection
|
||||
|
||||
|
@ -407,6 +422,8 @@ namespace WSQuery
|
|||
|
||||
### execute SQL with reqId
|
||||
|
||||
<RequestId />
|
||||
|
||||
<Tabs defaultValue="native" groupId="connect">
|
||||
<TabItem value="native" label="native connection">
|
||||
|
||||
|
@ -800,6 +817,10 @@ The configuration parameters supported by consumer are as follows:
|
|||
* auto.commit.interval.ms: The interval for automatically submitting offsets, the default is 5000 milliseconds
|
||||
* auto.offset.reset: When offset does not exist, where to start consumption, the optional value is earliest or latest, the default is latest
|
||||
* msg.with.table.name: Whether the message contains the table name
|
||||
* ws.message.enableCompression: Whether to enable WebSocket compression (effective for dotnet version 6 and above, connector version 3.1.1 and above). The default is false.
|
||||
* ws.autoReconnect: Whether to enable WebSocket reconnect (connector version 3.1.3 and above). The default is false.
|
||||
* ws.reconnect.retry.count: The number of reconnection retries (connector version 3.1.3 and above). The default is 3.
|
||||
* ws.reconnect.interval.ms: The interval between reconnection retries (connector version 3.1.3 and above). The default is 2000.
|
||||
|
||||
Supports subscribing to the result set `Dictionary<string, object>` where the key is the column name and the value is the column value.
|
||||
|
||||
|
|
|
@ -6,32 +6,35 @@ title: TDengine ODBC
|
|||
|
||||
## Introduction
|
||||
|
||||
TDengine ODBC driver is a driver specifically designed for TDengine based on the ODBC standard. It can be used by ODBC based applications on Windows to access a local or remote TDengine cluster or TDengine cloud service, like [PowerBI](https://powerbi.microsoft.com).
|
||||
The TDengine ODBC driver is a driver specifically designed for TDengine based on the ODBC standard. It can be used by ODBC based applications,like [PowerBI](https://powerbi.microsoft.com), on Windows, to access a local or remote TDengine cluster or an instance in the TDengine Cloud service.
|
||||
|
||||
TDengine ODBC provides two kinds of connections, native connection and WebSocket connection. You can choose to use either one for your convenience, WebSocket is recommded choice and you must use WebSocket if you are trying to access TDengine cloud service.
|
||||
TDengine ODBC provides two kinds of connections, native connection and WebSocket connection. You can choose to use either one for your convenience. WebSocket is the recommended choice and you must use WebSocket if you are trying to access an instance in the TDengine Cloud service.
|
||||
|
||||
Note: TDengine ODBC driver can only be run on 64-bit system, and can only be invoked by 64-bit applications.
|
||||
Note: TDengine ODBC driver can only be run on 64-bit systems, and can only be invoked by 64-bit applications.
|
||||
|
||||
## Compatibility with ODBC Versions
|
||||
|
||||
- TDengine ODBC driver compatible with ODBC 3.8 and all earlier versions.
|
||||
|
||||
## Install
|
||||
|
||||
1. TDengine ODBC driver supports only Windows platform. To run on Windows, VisualStudio C Runtime library is required. If VisualStudio C Runtime Library is missing on your platform, you can download and install it from [VC Runtime Library](https://learn.microsoft.com/en-us/cpp/windows/latest-supported-vc-redist?view=msvc-170).
|
||||
1. The TDengine ODBC driver only supports the Windows platform. To run on Windows, the Microsoft Visual C++ Runtime library is required. If the Microsoft Visual C++ Runtime Library is missing on your platform, you can download and install it from [VC Runtime Library](https://learn.microsoft.com/en-us/cpp/windows/latest-supported-vc-redist?view=msvc-170).
|
||||
|
||||
2. Install TDengine client package for Windows, the version should be above 3.2.1.0, the client package includes both TDengine ODBC driver and some other necessary libraries that will be used in either native connection or WebSocket connection.
|
||||
2. Install TDengine Client package for Windows. The TDengine Client version should be above 3.2.1.0. The client package includes both the TDengine ODBC driver and some other necessary libraries that will be used in either native connection or WebSocket connection.
|
||||
|
||||
## Configure Data Source
|
||||
|
||||
### Connection Types
|
||||
|
||||
TDengine ODBC driver supports two kinds of connections to TDengine cluster, native connection and WebSocket connection, here is the major differences between them.
|
||||
TDengine ODBC driver supports two kinds of connections to TDengine cluster: native connection and WebSocket connection. The major differences between them are listed below.
|
||||
|
||||
1. Only WebSocket can connect to TDengine cloud service.
|
||||
1. Only a WebSocket connection can be used to connect to TDengine Cloud service.
|
||||
|
||||
2. Websocket connection is more compatible with different TDengine server versions, normally you don't need to uupgrade client package with the server side.
|
||||
2. A Websocket connection is more compatible with different TDengine server versions. Usually, you don't need to upgrade the TDengine Client package along with the server side.
|
||||
|
||||
3. Native connection normally has better performance, but you need to keep the version aligned with the server side.
|
||||
3. Native connections usually have better performance, but the TDengine Client version must be compatible with the TDengine server version.
|
||||
|
||||
4. For most users, it's recommended to use **WebSocket** connection, which has much better compatibility and almost same performance as native connection.
|
||||
4. For most users, it's recommended to use **WebSocket** connection, which has much better compatibility and almost the same performance as native connection.
|
||||
|
||||
### WebSocket Connection
|
||||
|
||||
|
@ -57,9 +60,9 @@ TDengine ODBC driver supports two kinds of connections to TDengine cluster, nati
|
|||
|
||||
4.6 [Password]: optional field, only used for connection testing in step 5;
|
||||
|
||||
5. Click "Test Connecting" to test whether the data source can be connectted; if successful, it will prompt "connecting success"
|
||||
5. Click "Test Connection" to test whether the connection to the data source is successful; if successful, it will prompt "Successfully connected to URL"
|
||||
|
||||
6. Click "OK" to sae the configuration and exit.
|
||||
6. Click "OK" to set the configuration and exit.
|
||||
|
||||
7. You can also select an already configured data source name in step 2 to change existing configuration.
|
||||
|
||||
|
@ -72,4 +75,4 @@ The steps are exactly same as "WebSocket" connection, except for you choose "Nat
|
|||
|
||||
## PowerBI
|
||||
|
||||
As an example, you can use PowerBI, which inovkes TDengine ODBC driver, to access TDengine, please refer to[Power BI](../../third-party/powerbi) for more details.
|
||||
As an example, you can use PowerBI, which invokes TDengine ODBC driver, to access TDengine, please refer to [Power BI](../../third-party/powerbi) for more details.
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
The reqId is very similar to TraceID in distributed tracing systems. In a distributed system, a request may need to pass through multiple services or modules to be completed. The reqId is used to identify and associate all related operations of this request, allowing us to track and understand the complete execution path of the request.
|
||||
Here are some primary usage of reqId:
|
||||
- **Request Tracing**: By associating the same reqId with all related operations of a request, we can trace the complete path of the request within the system.
|
||||
- **Performance Analysis**: By analyzing a request's reqId, we can understand the processing time of the request across various services or modules, thereby identifying performance bottlenecks.
|
||||
- **Fault Diagnosis**: When a request fails, we can identify the location of the issue by examining the reqId associated with that request.
|
||||
|
||||
If the user does not set a reqId, the client library will generate one randomly internally, but it is still recommended for the user to set it, as it can better associate with the user's request.
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 18 KiB |
|
@ -15,9 +15,9 @@ Currently, TDengine's native interface client libraries can support platforms su
|
|||
| -------------- | --------- | -------- | ---------- | ------ | ----------- | ------ | -------- | ----- |
|
||||
| **X86 64bit** | **Linux** | ● | ● | ● | ● | ● | ● | ● |
|
||||
| **X86 64bit** | **Win64** | ● | ● | ● | ● | ● | ● | ● |
|
||||
| **X86 64bit** | **macOS** | ○ | ● | ● | ○ | ○ | ● | ● |
|
||||
| **X86 64bit** | **macOS** | ● | ● | ● | ○ | ○ | ● | ● |
|
||||
| **ARM64** | **Linux** | ● | ● | ● | ● | ○ | ○ | ● |
|
||||
| **ARM64** | **macOS** | ○ | ● | ● | ○ | ○ | ● | ● |
|
||||
| **ARM64** | **macOS** | ● | ● | ● | ○ | ○ | ● | ● |
|
||||
|
||||
Where ● means the official test verification passed, ○ means the unofficial test verification passed, -- means no assurance.
|
||||
|
||||
|
@ -59,9 +59,9 @@ The different database framework specifications for various programming language
|
|||
| -------------------------------------- | ------------- | --------------- | ------------- | ------------- | ------------- | ------------- |
|
||||
| **Connection Management** | Support | Support | Support | Support | Support | Support |
|
||||
| **Regular Query** | Support | Support | Support | Support | Support | Support |
|
||||
| **Parameter Binding** | Supported | Supported | Support | Support | Not Supported | Support |
|
||||
| **Subscription (TMQ) ** | Supported | Support | Support | Not Supported | Not Supported | Support |
|
||||
| **Schemaless** | Supported | Supported | Supported | Not Supported | Not Supported | Not Supported |
|
||||
| **Parameter Binding** | Support | Support | Support | Support | Not Supported | Support |
|
||||
| **Subscription (TMQ) ** | Support | Support | Support | Support | Not Supported | Support |
|
||||
| **Schemaless** | Support | Support | Support | Support | Not Supported | Not Supported |
|
||||
| **Bulk Pulling (based on WebSocket) ** | Support | Support | Support | Support | Support | Support |
|
||||
|
||||
:::warning
|
||||
|
|
|
@ -173,12 +173,6 @@ Query OK, 8 row(s) in set (0.001154s)
|
|||
|
||||
Before running the TDengine CLI, ensure that the taosd process has been stopped on the dnode that you want to delete.
|
||||
|
||||
```sql
|
||||
DROP DNODE "fqdn:port";
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```sql
|
||||
DROP DNODE dnodeId;
|
||||
```
|
||||
|
|
|
@ -60,7 +60,7 @@ database_option: {
|
|||
- PAGES: specifies the number of pages in the metadata storage engine cache on each vnode. Enter a value greater than or equal to 64. The default value is 256. The space occupied by metadata storage on each vnode is equal to the product of the values of the PAGESIZE and PAGES parameters. The space occupied by default is 1 MB.
|
||||
- PAGESIZE: specifies the size (in KB) of each page in the metadata storage engine cache on each vnode. The default value is 4. Enter a value between 1 and 16384.
|
||||
- PRECISION: specifies the precision at which a database records timestamps. Enter ms for milliseconds, us for microseconds, or ns for nanoseconds. The default value is ms.
|
||||
- REPLICA: specifies the number of replicas that are made of the database. Enter 1 or 3. The default value is 1. The value of the REPLICA parameter cannot exceed the number of dnodes in the cluster.
|
||||
- REPLICA: specifies the number of replicas that are made of the database. Enter 1, 2 or 3. The default value is 1. 2 is only available in TDengine Enterprise since version 3.3.0.0. The value of the REPLICA parameter cannot exceed the number of dnodes in the cluster.
|
||||
- WAL_LEVEL: specifies whether fsync is enabled. The default value is 1.
|
||||
- 1: WAL is enabled but fsync is disabled.
|
||||
- 2: WAL and fsync are both enabled.
|
||||
|
|
|
@ -207,6 +207,8 @@ The following SQL statement deletes one or more tables.
|
|||
DROP TABLE [IF EXISTS] [db_name.]tb_name [, [IF EXISTS] [db_name.]tb_name] ...
|
||||
```
|
||||
|
||||
**Note**:Dropping a table doesn't release the disk space occupied by the table, instead all the rows in the table are marked as deleted, so these data will not occur when querying. The disk space will be released when the system automatically performs `compact` operation or the user performs `compact` manually.
|
||||
|
||||
## View Tables
|
||||
|
||||
### View All Tables
|
||||
|
|
|
@ -111,6 +111,8 @@ DROP STABLE [IF EXISTS] [db_name.]stb_name
|
|||
|
||||
Note: Deleting a supertable will delete all subtables created from the supertable, including all data within those subtables.
|
||||
|
||||
**Note**:Dropping a supertable doesn't release the disk space occupied by the table, instead all the rows in the table are marked as deleted, so these data will not occur when querying. The disk space will be released when the system automatically performs `compact` operation or the user performs `compact` manually.
|
||||
|
||||
## Modify a Supertable
|
||||
|
||||
```sql
|
||||
|
|
|
@ -148,6 +148,11 @@ You can query tag columns in supertables and subtables and receive results in th
|
|||
SELECT location, groupid, current FROM d1001 LIMIT 2;
|
||||
```
|
||||
|
||||
### Alias Name
|
||||
|
||||
The naming rules for aliases are the same as those for columns, and it supports directly specifying Chinese aliases in UTF-8 encoding format.
|
||||
|
||||
|
||||
### Distinct Values
|
||||
|
||||
The DISTINCT keyword returns only values that are different over one or more columns. You can use the DISTINCT keyword with tag columns and data columns.
|
||||
|
@ -278,7 +283,7 @@ The GROUP BY clause does not guarantee that the results are ordered. If you want
|
|||
|
||||
The PARTITION BY clause is a TDengine-specific extension to standard SQL introduced in TDengine 3.0. This clause partitions data based on the part_list and performs computations per partition.
|
||||
|
||||
PARTITION BY and GROUP BY have similar meanings. They both group data according to a specified list and then perform calculations. The difference is that PARTITION BY does not have various restrictions on the SELECT list of the GROUP BY clause. Any operation can be performed within the group (constants, aggregations, scalars, expressions, etc.). Therefore, PARTITION BY is fully compatible with GROUP BY in terms of usage. All places that use the GROUP BY clause can be replaced with PARTITION BY.
|
||||
PARTITION BY and GROUP BY have similar meanings. They both group data according to a specified list and then perform calculations. The difference is that PARTITION BY does not have various restrictions on the SELECT list of the GROUP BY clause. Any operation can be performed within the group (constants, aggregations, scalars, expressions, etc.). Therefore, PARTITION BY is fully compatible with GROUP BY in terms of usage. All places that use the GROUP BY clause can be replaced with PARTITION BY, there may be differences in the query results while no aggregation function in the query.
|
||||
|
||||
Because PARTITION BY does not require returning a row of aggregated data, it can also support various window operations after grouping slices. All window operations that need to be grouped can only use the PARTITION BY clause.
|
||||
|
||||
|
@ -454,6 +459,7 @@ SELECT ... FROM (SELECT ... FROM ...) ...;
|
|||
:::info
|
||||
|
||||
- The result of a nested query is returned as a virtual table used by the outer query. It's recommended to give an alias to this table for the convenience of using it in the outer query.
|
||||
- Outer queries support directly referencing columns or pseudo-columns of inner queries in the form of column names or `column names`.
|
||||
- JOIN operation is allowed between tables/STables inside both inner and outer queries. Join operation can be performed on the result set of the inner query.
|
||||
- The features that can be used in the inner query are the same as those that can be used in a non-nested query.
|
||||
- `ORDER BY` inside the inner query is unnecessary and will slow down the query performance significantly. It is best to avoid the use of `ORDER BY` inside the inner query.
|
||||
|
|
|
@ -6,6 +6,8 @@ description: This document describes how to delete data from TDengine.
|
|||
|
||||
TDengine provides the functionality of deleting data from a table or STable according to specified time range, it can be used to cleanup abnormal data generated due to device failure.
|
||||
|
||||
**Note**:Deletting some data doesn't release the disk space occupied by the table, instead all the rows in the table are marked as deleted, so these data will not occur when querying. The disk space will be released when the system automatically performs `compact` operation or the user performs `compact` manually.
|
||||
|
||||
**Syntax:**
|
||||
|
||||
```sql
|
||||
|
|
|
@ -1167,7 +1167,7 @@ TDengine includes extensions to standard SQL that are intended specifically for
|
|||
CSUM(expr)
|
||||
```
|
||||
|
||||
**Description**: The cumulative sum of each row for a specific column. The number of output rows is same as that of the input rows.
|
||||
**Description**: The cumulative sum of each row for a specific column, NULL value will be discard.
|
||||
|
||||
**Return value type**: Long integer for integers; Double for floating points. uint64_t for unsigned integers
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ A PARTITION BY clause is processed as follows:
|
|||
select _wstart, location, max(current) from meters partition by location interval(10m)
|
||||
```
|
||||
|
||||
The most common usage of PARTITION BY is partitioning the data in subtables by tags then perform computation when querying data in a supertable. More specifically, `PARTITION BY TBNAME` partitions the data of each subtable into a single timeline, and this method facilitates the statistical analysis in many use cases of processing timeseries data. For example, calculate the average voltage of each meter every 10 minutes£º
|
||||
The most common usage of PARTITION BY is partitioning the data in subtables by tags then perform computation when querying data in a supertable. More specifically, `PARTITION BY TBNAME` partitions the data of each subtable into a single timeline, and this method facilitates the statistical analysis in many use cases of processing timeseries data. For example, calculate the average voltage of each meter every 10 minutes:
|
||||
```sql
|
||||
select _wstart, tbname, avg(voltage) from meters partition by tbname interval(10m)
|
||||
```
|
||||
|
|
|
@ -78,6 +78,10 @@ If a stream is created with PARTITION BY clause and SUBTABLE clause, the name of
|
|||
|
||||
```sql
|
||||
CREATE STREAM avg_vol_s INTO avg_vol SUBTABLE(CONCAT('new-', tname)) AS SELECT _wstart, count(*), avg(voltage) FROM meters PARTITION BY tbname tname INTERVAL(1m);
|
||||
|
||||
CREATE STREAM streams0 INTO streamt0 AS SELECT _wstart, count(*), avg(voltage) from meters PARTITION BY tbname EVENT_WINDOW START WITH voltage < 0 END WITH voltage > 9;
|
||||
|
||||
CREATE STREAM streams1 IGNORE EXPIRED 1 WATERMARK 100s INTO streamt1 AS SELECT _wstart, count(*), avg(voltage) from meters PARTITION BY tbname COUNT_WINDOW(10);
|
||||
```
|
||||
|
||||
IN PARTITION clause, 'tbname', representing each subtable name of source supertable, is given alias 'tname'. And 'tname' is used in SUBTABLE clause. In SUBTABLE clause, each auto created subtable will concat 'new-' and source subtable name as their name(Starting from 3.2.3.0, in order to avoid the expression in subtable being unable to distinguish between different subtables, add '_stableName_groupId' to the end of subtable name).
|
||||
|
|
|
@ -27,10 +27,10 @@ The preceding SQL command shows all dnodes in the cluster with the ID, endpoint,
|
|||
## Delete a DNODE
|
||||
|
||||
```sql
|
||||
DROP DNODE {dnode_id | dnode_endpoint}
|
||||
DROP DNODE dnode_id
|
||||
```
|
||||
|
||||
You can delete a dnode by its ID or by its endpoint. Note that deleting a dnode does not stop its process. You must stop the process after the dnode is deleted.
|
||||
Note that deleting a dnode does not stop its process. You must stop the process after the dnode is deleted.
|
||||
|
||||
## Modify Dnode Configuration
|
||||
|
||||
|
|
|
@ -210,9 +210,13 @@ Provides information about TDengine users. Users whose SYSINFO attribute is 0 ca
|
|||
|
||||
| # | **Column** | **Data Type** | **Description** |
|
||||
| --- | :---------: | ------------- | ---------------- |
|
||||
| 1 | user_name | VARCHAR(23) | User name |
|
||||
| 2 | privilege | VARCHAR(256) | User permissions |
|
||||
| 3 | create_time | TIMESTAMP | Creation time |
|
||||
| 1 | name | VARCHAR(24) | User name |
|
||||
| 2 | super | TINYINT | Wether user is super user. 1 means yes; 0 means no. |
|
||||
| 3 | enable | TINYINT | Wether user is enabled. 1 means yes; 0 means no. |
|
||||
| 4 | sysinfo | TINYINT | Wether user can query system info. 1 means yes; 0 means no. |
|
||||
| 5 | create_time | TIMESTAMP | Create time |
|
||||
| 6 | allowed_host | VARCHAR(49152)| IP whitelist |
|
||||
|
||||
|
||||
## INS_GRANTS
|
||||
|
||||
|
|
|
@ -91,53 +91,4 @@ Query OK, 0 of 0 rows affected (0.001160s)
|
|||
|
||||
## Grant Permissions
|
||||
|
||||
```sql
|
||||
GRANT privileges ON priv_level TO user_name
|
||||
|
||||
privileges : {
|
||||
ALL
|
||||
| priv_type [, priv_type] ...
|
||||
}
|
||||
|
||||
priv_type : {
|
||||
READ
|
||||
| WRITE
|
||||
}
|
||||
|
||||
priv_level : {
|
||||
dbname.*
|
||||
| *.*
|
||||
}
|
||||
```
|
||||
|
||||
Grant permissions to a user, this feature is only available in enterprise edition.
|
||||
|
||||
Permissions are granted on the database level. You can grant read or write permissions.
|
||||
|
||||
TDengine has superusers and standard users. The default superuser name is root. This account has all permissions. You can use the superuser account to create standard users. With no permissions, standard users can create databases and have permissions on the databases that they create. These include deleting, modifying, querying, and writing to their own databases. Superusers can grant users permission to read and write other databases. However, standard users cannot delete or modify databases created by other users.
|
||||
|
||||
For non-database objects such as users, dnodes, and user-defined functions, standard users have read permissions only, generally by means of the SHOW statement. Standard users cannot create or modify these objects.
|
||||
|
||||
## Revoke Permissions
|
||||
|
||||
```sql
|
||||
REVOKE privileges ON priv_level FROM user_name
|
||||
|
||||
privileges : {
|
||||
ALL
|
||||
| priv_type [, priv_type] ...
|
||||
}
|
||||
|
||||
priv_type : {
|
||||
READ
|
||||
| WRITE
|
||||
}
|
||||
|
||||
priv_level : {
|
||||
dbname.*
|
||||
| *.*
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Revoke permissions from a user, this feature is only available in enterprise edition.
|
||||
Permission control is only available in TDengine Enterprise, please contact TDengine sales team.
|
|
@ -53,7 +53,7 @@ CREATE AGGREGATE FUNCTION function_name AS library_path OUTPUTTYPE output_type [
|
|||
CREATE AGGREGATE FUNCTION l2norm AS "/home/taos/udf_example/libl2norm.so" OUTPUTTYPE DOUBLE bufsize 64;
|
||||
```
|
||||
|
||||
For more information about user-defined functions, see [User-Defined Functions](../../develop/udf).
|
||||
For more information about user-defined functions, see [User-Defined Functions](https://docs.tdengine.com/develop/udf/).
|
||||
|
||||
## Manage UDF
|
||||
|
||||
|
|
|
@ -43,201 +43,204 @@ Launch `TDinsight.sh` with the command above and restart Grafana, then open Dash
|
|||
|
||||
The data of tdinsight dashboard is stored in `log` database (default. You can change it in taoskeeper's config file. For more infrmation, please reference to [taoskeeper document](../../reference/taosKeeper)). The taoskeeper will create log database on taoskeeper startup.
|
||||
|
||||
### cluster\_info table
|
||||
### taosd\_cluster\_basic table
|
||||
|
||||
`cluster_info` table contains cluster information records.
|
||||
`taosd_cluster_basic` table contains cluster basic information.
|
||||
|
||||
|field|type|is\_tag|comment|
|
||||
|:----|:---|:-----|:------|
|
||||
|ts|TIMESTAMP||timestamp|
|
||||
|first\_ep|VARCHAR||first ep of cluster|
|
||||
|first\_ep\_dnode\_id|INT||dnode id or first\_ep|
|
||||
|version|VARCHAR||tdengine version. such as: 3.0.4.0|
|
||||
|master\_uptime|FLOAT||days of master's uptime|
|
||||
|monitor\_interval|INT||monitor interval in second|
|
||||
|dbs\_total|INT||total number of databases in cluster|
|
||||
|tbs\_total|BIGINT||total number of tables in cluster|
|
||||
|stbs\_total|INT||total number of stables in cluster|
|
||||
|dnodes\_total|INT||total number of dnodes in cluster|
|
||||
|dnodes\_alive|INT||total number of dnodes in ready state|
|
||||
|mnodes\_total|INT||total number of mnodes in cluster|
|
||||
|mnodes\_alive|INT||total number of mnodes in ready state|
|
||||
|vgroups\_total|INT||total number of vgroups in cluster|
|
||||
|vgroups\_alive|INT||total number of vgroups in ready state|
|
||||
|vnodes\_total|INT||total number of vnode in cluster|
|
||||
|vnodes\_alive|INT||total number of vnode in ready state|
|
||||
|connections\_total|INT||total number of connections to cluster|
|
||||
|topics\_total|INT||total number of topics in cluster|
|
||||
|streams\_total|INT||total number of streams in cluster|
|
||||
|protocol|INT||protocol version|
|
||||
|cluster\_id|NCHAR|TAG|cluster id|
|
||||
|cluster_version|VARCHAR||tdengine version. such as: 3.0.4.0|
|
||||
|cluster\_id|VARCHAR|TAG|cluster id|
|
||||
|
||||
### d\_info table
|
||||
### taosd\_cluster\_info table
|
||||
|
||||
`d_info` table contains dnodes information records.
|
||||
`taosd_cluster_info` table contains cluster information records.
|
||||
|
||||
|field|type|is\_tag|comment|
|
||||
|:----|:---|:-----|:------|
|
||||
|ts|TIMESTAMP||timestamp|
|
||||
|status|VARCHAR||dnode status|
|
||||
|dnode\_ep|NCHAR|TAG|dnode endpoint|
|
||||
|cluster\_id|NCHAR|TAG|cluster id|
|
||||
|cluster\_uptime|DOUBLE||seconds of master's uptime|
|
||||
|dbs\_total|DOUBLE||total number of databases in cluster|
|
||||
|tbs\_total|DOUBLE||total number of tables in cluster|
|
||||
|stbs\_total|DOUBLE||total number of stables in cluster|
|
||||
|dnodes\_total|DOUBLE||total number of dnodes in cluster|
|
||||
|dnodes\_alive|DOUBLE||total number of dnodes in ready state|
|
||||
|mnodes\_total|DOUBLE||total number of mnodes in cluster|
|
||||
|mnodes\_alive|DOUBLE||total number of mnodes in ready state|
|
||||
|vgroups\_total|DOUBLE||total number of vgroups in cluster|
|
||||
|vgroups\_alive|DOUBLE||total number of vgroups in ready state|
|
||||
|vnodes\_total|DOUBLE||total number of vnode in cluster|
|
||||
|vnodes\_alive|DOUBLE||total number of vnode in ready state|
|
||||
|connections\_total|DOUBLE||total number of connections to cluster|
|
||||
|topics\_total|DOUBLE||total number of topics in cluster|
|
||||
|streams\_total|DOUBLE||total number of streams in cluster|
|
||||
|grants_expire\_time|DOUBLE||time until grants expire in seconds|
|
||||
|grants_timeseries\_used|DOUBLE||timeseries used|
|
||||
|grants_timeseries\_total|DOUBLE||total timeseries|
|
||||
|cluster\_id|VARCHAR|TAG|cluster id|
|
||||
|
||||
### m\_info table
|
||||
### taosd\_vgroups\_info table
|
||||
|
||||
`m_info` table contains mnode information records.
|
||||
`taosd_vgroups_info` table contains vgroups information records.
|
||||
|
||||
|field|type|is\_tag|comment|
|
||||
|:----|:---|:-----|:------|
|
||||
|ts|TIMESTAMP||timestamp|
|
||||
|role|VARCHAR||the role of mnode. leader or follower|
|
||||
|mnode\_id|INT|TAG|master node id|
|
||||
|mnode\_ep|NCHAR|TAG|master node endpoint|
|
||||
|cluster\_id|NCHAR|TAG|cluster id|
|
||||
|tables\_num|DOUBLE||number of tables per vgroup|
|
||||
|status|DOUBLE||status, value range:unsynced = 0, ready = 1|
|
||||
|vgroup\_id|VARCHAR|TAG|vgroup id|
|
||||
|database\_name|VARCHAR|TAG|database for the vgroup|
|
||||
|cluster\_id|VARCHAR|TAG|cluster id|
|
||||
|
||||
### dnodes\_info table
|
||||
### taosd\_dnodes\_info table
|
||||
|
||||
`dnodes_info` table contains dnodes information records.
|
||||
`taosd_dnodes_info` table contains dnodes information records.
|
||||
|
||||
|field|type|is\_tag|comment|
|
||||
|:----|:---|:-----|:------|
|
||||
|ts|TIMESTAMP||timestamp|
|
||||
|uptime|FLOAT||dnode uptime in `days`|
|
||||
|cpu\_engine|FLOAT||cpu usage of tdengine. read from `/proc/<taosd_pid>/stat`|
|
||||
|cpu\_system|FLOAT||cpu usage of server. read from `/proc/stat`|
|
||||
|cpu\_cores|FLOAT||cpu cores of server|
|
||||
|mem\_engine|INT||memory usage of tdengine. read from `/proc/<taosd_pid>/status`|
|
||||
|mem\_system|INT||available memory on the server in `KB`|
|
||||
|mem\_total|INT||total memory of server in `KB`|
|
||||
|disk\_engine|INT|||
|
||||
|disk\_used|BIGINT||usage of data dir in `bytes`|
|
||||
|disk\_total|BIGINT||the capacity of data dir in `bytes`|
|
||||
|net\_in|FLOAT||network throughput rate in byte/s. read from `/proc/net/dev`|
|
||||
|net\_out|FLOAT||network throughput rate in byte/s. read from `/proc/net/dev`|
|
||||
|io\_read|FLOAT||io throughput rate in byte/s. read from `/proc/<taosd_pid>/io`|
|
||||
|io\_write|FLOAT||io throughput rate in byte/s. read from `/proc/<taosd_pid>/io`|
|
||||
|io\_read\_disk|FLOAT||io throughput rate of disk in byte/s. read from `/proc/<taosd_pid>/io`|
|
||||
|io\_write\_disk|FLOAT||io throughput rate of disk in byte/s. read from `/proc/<taosd_pid>/io`|
|
||||
|req\_select|INT||number of select queries received per dnode|
|
||||
|req\_select\_rate|FLOAT||number of select queries received per dnode divided by monitor interval.|
|
||||
|req\_insert|INT||number of insert queries received per dnode|
|
||||
|req\_insert\_success|INT||number of successfully insert queries received per dnode|
|
||||
|req\_insert\_rate|FLOAT||number of insert queries received per dnode divided by monitor interval|
|
||||
|req\_insert\_batch|INT||number of batch insertions|
|
||||
|req\_insert\_batch\_success|INT||number of successful batch insertions|
|
||||
|req\_insert\_batch\_rate|FLOAT||number of batch insertions divided by monitor interval|
|
||||
|errors|INT||dnode errors|
|
||||
|vnodes\_num|INT||number of vnodes per dnode|
|
||||
|masters|INT||number of master vnodes|
|
||||
|has\_mnode|INT||if the dnode has mnode|
|
||||
|has\_qnode|INT||if the dnode has qnode|
|
||||
|has\_snode|INT||if the dnode has snode|
|
||||
|has\_bnode|INT||if the dnode has bnode|
|
||||
|dnode\_id|INT|TAG|dnode id|
|
||||
|dnode\_ep|NCHAR|TAG|dnode endpoint|
|
||||
|cluster\_id|NCHAR|TAG|cluster id|
|
||||
|uptime|DOUBLE||dnode uptime in `seconds`|
|
||||
|cpu\_engine|DOUBLE||cpu usage of tdengine. read from `/proc/<taosd_pid>/stat`|
|
||||
|cpu\_system|DOUBLE||cpu usage of server. read from `/proc/stat`|
|
||||
|cpu\_cores|DOUBLE||cpu cores of server|
|
||||
|mem\_engine|DOUBLE||memory usage of tdengine. read from `/proc/<taosd_pid>/status`|
|
||||
|mem\_free|DOUBLE||available memory on the server in `KB`|
|
||||
|mem\_total|DOUBLE||total memory of server in `KB`|
|
||||
|disk\_used|DOUBLE||usage of data dir in `bytes`|
|
||||
|disk\_total|DOUBLE||the capacity of data dir in `bytes`|
|
||||
|system\_net\_in|DOUBLE||network throughput rate in byte/s. read from `/proc/net/dev`|
|
||||
|system\_net\_out|DOUBLE||network throughput rate in byte/s. read from `/proc/net/dev`|
|
||||
|io\_read|DOUBLE||io throughput rate in byte/s. read from `/proc/<taosd_pid>/io`|
|
||||
|io\_write|DOUBLE||io throughput rate in byte/s. read from `/proc/<taosd_pid>/io`|
|
||||
|io\_read\_disk|DOUBLE||io throughput rate of disk in byte/s. read from `/proc/<taosd_pid>/io`|
|
||||
|io\_write\_disk|DOUBLE||io throughput rate of disk in byte/s. read from `/proc/<taosd_pid>/io`|
|
||||
|vnodes\_num|DOUBLE||number of vnodes per dnode|
|
||||
|masters|DOUBLE||number of master vnodes|
|
||||
|has\_mnode|DOUBLE||if the dnode has mnode, value range:include=1, not_include=0|
|
||||
|has\_qnode|DOUBLE||if the dnode has qnode, value range:include=1, not_include=0|
|
||||
|has\_snode|DOUBLE||if the dnode has snode, value range:include=1, not_include=0|
|
||||
|has\_bnode|DOUBLE||if the dnode has bnode, value range:include=1, not_include=0|
|
||||
|error\_log\_count|DOUBLE||error count|
|
||||
|info\_log\_count|DOUBLE||info count|
|
||||
|debug\_log\_count|DOUBLE||debug count|
|
||||
|trace\_log\_count|DOUBLE||trace count|
|
||||
|dnode\_id|VARCHAR|TAG|dnode id|
|
||||
|dnode\_ep|VARCHAR|TAG|dnode endpoint|
|
||||
|cluster\_id|VARCHAR|TAG|cluster id|
|
||||
|
||||
### data\_dir table
|
||||
### taosd\_dnodes\_status table
|
||||
|
||||
`data_dir` table contains data directory information records.
|
||||
`taosd_dnodes_status` table contains dnodes information records.
|
||||
|
||||
|field|type|is\_tag|comment|
|
||||
|:----|:---|:-----|:------|
|
||||
|ts|TIMESTAMP||timestamp|
|
||||
|name|NCHAR||data directory. default is `/var/lib/taos`|
|
||||
|level|INT||level for multi-level storage|
|
||||
|avail|BIGINT||available space for data directory in `bytes`|
|
||||
|used|BIGINT||used space for data directory in `bytes`|
|
||||
|total|BIGINT||total space for data directory in `bytes`|
|
||||
|dnode\_id|INT|TAG|dnode id|
|
||||
|dnode\_ep|NCHAR|TAG|dnode endpoint|
|
||||
|cluster\_id|NCHAR|TAG|cluster id|
|
||||
|status|DOUBLE||dnode status, value range:ready=1,offline =0|
|
||||
|dnode\_id|VARCHAR|TAG|dnode id|
|
||||
|dnode\_ep|VARCHAR|TAG|dnode endpoint|
|
||||
|cluster\_id|VARCHAR|TAG|cluster id|
|
||||
|
||||
### log\_dir table
|
||||
### taosd\_dnodes\_log\_dir table
|
||||
|
||||
`log_dir` table contains log directory information records.
|
||||
|
||||
|field|type|is\_tag|comment|
|
||||
|:----|:---|:-----|:------|
|
||||
|ts|TIMESTAMP||timestamp|
|
||||
|name|NCHAR||log directory. default is `/var/log/taos/`|
|
||||
|avail|BIGINT||available space for log directory in `bytes`|
|
||||
|used|BIGINT||used space for data directory in `bytes`|
|
||||
|total|BIGINT||total space for data directory in `bytes`|
|
||||
|dnode\_id|INT|TAG|dnode id|
|
||||
|dnode\_ep|NCHAR|TAG|dnode endpoint|
|
||||
|cluster\_id|NCHAR|TAG|cluster id|
|
||||
|avail|DOUBLE||available space for log directory in `bytes`|
|
||||
|used|DOUBLE||used space for data directory in `bytes`|
|
||||
|total|DOUBLE||total space for data directory in `bytes`|
|
||||
|name|VARCHAR|TAG|log directory. default is `/var/log/taos/`|
|
||||
|dnode\_id|VARCHAR|TAG|dnode id|
|
||||
|dnode\_ep|VARCHAR|TAG|dnode endpoint|
|
||||
|cluster\_id|VARCHAR|TAG|cluster id|
|
||||
|
||||
### temp\_dir table
|
||||
### taosd\_dnodes\_data\_dir table
|
||||
|
||||
`temp_dir` table contains temp dir information records.
|
||||
`taosd_dnodes_data_dir` table contains data directory information records.
|
||||
|
||||
|field|type|is\_tag|comment|
|
||||
|:----|:---|:-----|:------|
|
||||
|ts|TIMESTAMP||timestamp|
|
||||
|name|NCHAR||temp directory. default is `/tmp/`|
|
||||
|avail|BIGINT||available space for temp directory in `bytes`|
|
||||
|used|BIGINT||used space for temp directory in `bytes`|
|
||||
|total|BIGINT||total space for temp directory in `bytes`|
|
||||
|dnode\_id|INT|TAG|dnode id|
|
||||
|dnode\_ep|NCHAR|TAG|dnode endpoint|
|
||||
|cluster\_id|NCHAR|TAG|cluster id|
|
||||
|avail|DOUBLE||available space for data directory in `bytes`|
|
||||
|used|DOUBLE||used space for data directory in `bytes`|
|
||||
|total|DOUBLE||total space for data directory in `bytes`|
|
||||
|level|VARCHAR|TAG|level for multi-level storage|
|
||||
|name|VARCHAR|TAG|data directory. default is `/var/lib/taos`|
|
||||
|dnode\_id|VARCHAR|TAG|dnode id|
|
||||
|dnode\_ep|VARCHAR|TAG|dnode endpoint|
|
||||
|cluster\_id|VARCHAR|TAG|cluster id|
|
||||
|
||||
### vgroups\_info table
|
||||
### taosd\_mnodes\_info table
|
||||
|
||||
`vgroups_info` table contains vgroups information records.
|
||||
`taosd_mnodes_info` table contains mnode information records.
|
||||
|
||||
|field|type|is\_tag|comment|
|
||||
|:----|:---|:-----|:------|
|
||||
|ts|TIMESTAMP||timestamp|
|
||||
|vgroup\_id|INT||vgroup id|
|
||||
|database\_name|VARCHAR||database for the vgroup|
|
||||
|tables\_num|BIGINT||number of tables per vgroup|
|
||||
|status|VARCHAR||status|
|
||||
|dnode\_id|INT|TAG|dnode id|
|
||||
|dnode\_ep|NCHAR|TAG|dnode endpoint|
|
||||
|cluster\_id|NCHAR|TAG|cluster id|
|
||||
|role|DOUBLE||the role of mnode. value range:offline = 0,follower = 100,candidate = 101,leader = 102,error = 103,learner = 104|
|
||||
|mnode\_id|VARCHAR|TAG|master node id|
|
||||
|mnode\_ep|VARCHAR|TAG|master node endpoint|
|
||||
|cluster\_id|VARCHAR|TAG|cluster id|
|
||||
|
||||
### vnodes\_role table
|
||||
### taosd\_vnodes\_role table
|
||||
|
||||
`vnodes_role` table contains vnode role information records.
|
||||
`taosd_vnodes_role` table contains vnode role information records.
|
||||
|
||||
|field|type|is\_tag|comment|
|
||||
|:----|:---|:-----|:------|
|
||||
|ts|TIMESTAMP||timestamp|
|
||||
|vnode\_role|VARCHAR||role. leader or follower|
|
||||
|dnode\_id|INT|TAG|dnode id|
|
||||
|dnode\_ep|NCHAR|TAG|dnode endpoint|
|
||||
|cluster\_id|NCHAR|TAG|cluster id|
|
||||
|role|DOUBLE||role. value range:offline = 0,follower = 100,candidate = 101,leader = 102,error = 103,learner = 104|
|
||||
|vgroup\_id|VARCHAR|TAG|vgroup id|
|
||||
|database\_name|VARCHAR|TAG|database for the vgroup|
|
||||
|dnode\_id|VARCHAR|TAG|dnode id|
|
||||
|cluster\_id|VARCHAR|TAG|cluster id|
|
||||
|
||||
### log\_summary table
|
||||
### taosd\_sql\_req table
|
||||
|
||||
`log_summary` table contains log summary information records.
|
||||
`taosd_sql_req` tables contains taosd sql records.
|
||||
|
||||
|field|type|is\_tag|comment|
|
||||
|:----|:---|:-----|:------|
|
||||
|ts|TIMESTAMP||timestamp|
|
||||
|error|INT||error count|
|
||||
|info|INT||info count|
|
||||
|debug|INT||debug count|
|
||||
|trace|INT||trace count|
|
||||
|dnode\_id|INT|TAG|dnode id|
|
||||
|dnode\_ep|NCHAR|TAG|dnode endpoint|
|
||||
|cluster\_id|NCHAR|TAG|cluster id|
|
||||
|count|DOUBLE||sql count|
|
||||
|result|VARCHAR|TAG|sql execution result,value range: Success, Failed|
|
||||
|username|VARCHAR|TAG|user name who executed the sql|
|
||||
|sql\_type|VARCHAR|TAG|sql type,value range:inserted_rows|
|
||||
|dnode\_id|VARCHAR|TAG|dnode id|
|
||||
|dnode\_ep|VARCHAR|TAG|dnode endpoint|
|
||||
|vgroup\_id|VARCHAR|TAG|dnode id|
|
||||
|cluster\_id|VARCHAR|TAG|cluster id|
|
||||
|
||||
### grants\_info table
|
||||
### taos\_sql\_req 表
|
||||
|
||||
`grants_info` table contains grants information records.
|
||||
`taos_sql_req` tables contains taos sql records.
|
||||
|
||||
|field|type|is\_tag|comment|
|
||||
|:----|:---|:-----|:------|
|
||||
|ts|TIMESTAMP||timestamp|
|
||||
|expire\_time|BIGINT||time until grants expire in seconds|
|
||||
|timeseries\_used|BIGINT||timeseries used|
|
||||
|timeseries\_total|BIGINT||total timeseries|
|
||||
|dnode\_id|INT|TAG|dnode id|
|
||||
|dnode\_ep|NCHAR|TAG|dnode endpoint|
|
||||
|cluster\_id|NCHAR|TAG|cluster id|
|
||||
|count|DOUBLE||sql count|
|
||||
|result|VARCHAR|TAG|sql execution result,value range: Success, Failed|
|
||||
|username|VARCHAR|TAG|user name who executed the sql|
|
||||
|sql\_type|VARCHAR|TAG|sql type,value range:select, insert,delete|
|
||||
|cluster\_id|VARCHAR|TAG|cluster id|
|
||||
|
||||
### taos\_slow\_sql 表
|
||||
|
||||
`taos_slow_sql` ables contains taos slow sql records.
|
||||
|
||||
|field|type|is\_tag|comment|
|
||||
|:----|:---|:-----|:------|
|
||||
|ts|TIMESTAMP||timestamp|
|
||||
|count|DOUBLE||sql count|
|
||||
|result|VARCHAR|TAG|sql execution result,value range: Success, Failed|
|
||||
|username|VARCHAR|TAG|user name who executed the sql|
|
||||
|duration|VARCHAR|TAG|sql execution duration,value range:3-10s,10-100s,100-1000s,1000s-|
|
||||
|cluster\_id|VARCHAR|TAG|cluster id|
|
||||
|
||||
|
||||
### keeper\_monitor table
|
||||
|
||||
|
|
|
@ -68,7 +68,7 @@ The following return value results indicate that the verification passed.
|
|||
## HTTP request URL format
|
||||
|
||||
```text
|
||||
http://<fqdn>:<port>/rest/sql/[db_name][?tz=timezone[&req_id=req_id]]
|
||||
http://<fqdn>:<port>/rest/sql/[db_name][?tz=timezone[&req_id=req_id][&row_with_meta=true]]
|
||||
```
|
||||
|
||||
Parameter Description:
|
||||
|
@ -78,6 +78,7 @@ Parameter Description:
|
|||
- db_name: Optional parameter that specifies the default database name for the executed SQL command.
|
||||
- tz: Optional parameter that specifies the timezone of the returned time, following the IANA Time Zone rules, e.g. `America/New_York`.
|
||||
- req_id: Optional parameter that specifies the request id for tracing.
|
||||
- row_with_meta: Optional parameter that specifies whether each row of data carries the column name. The default value is `false`.(Supported starting from version 3.3.2.0)
|
||||
|
||||
:::note
|
||||
|
||||
|
@ -336,6 +337,82 @@ Description:
|
|||
- code: (`int`) Error code.
|
||||
- desc: (`string`): Error code description.
|
||||
|
||||
#### Return key-value pair
|
||||
|
||||
When the parameter `row_with_meta=true` is specified, the data returned in `data` field will change from array format to object format, where the key of the object is the column name and the value is the data.
|
||||
|
||||
insert response example:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 0,
|
||||
"column_meta": [
|
||||
[
|
||||
"affected_rows",
|
||||
"INT",
|
||||
4
|
||||
]
|
||||
],
|
||||
"data": [
|
||||
{
|
||||
"affected_rows": 1
|
||||
}
|
||||
],
|
||||
"rows": 1
|
||||
}
|
||||
```
|
||||
|
||||
query response example:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 0,
|
||||
"column_meta": [
|
||||
[
|
||||
"ts",
|
||||
"TIMESTAMP",
|
||||
8
|
||||
],
|
||||
[
|
||||
"current",
|
||||
"FLOAT",
|
||||
4
|
||||
],
|
||||
[
|
||||
"voltage",
|
||||
"INT",
|
||||
4
|
||||
],
|
||||
[
|
||||
"phase",
|
||||
"FLOAT",
|
||||
4
|
||||
],
|
||||
[
|
||||
"groupid",
|
||||
"INT",
|
||||
4
|
||||
],
|
||||
[
|
||||
"location",
|
||||
"VARCHAR",
|
||||
24
|
||||
]
|
||||
],
|
||||
"data": [
|
||||
{
|
||||
"ts": "2017-07-14T02:40:00.000Z",
|
||||
"current": -2.498076,
|
||||
"voltage": 0,
|
||||
"phase": -0.846025,
|
||||
"groupid": 8,
|
||||
"location": "California.Sunnyvale"
|
||||
}
|
||||
],
|
||||
"rows": 1
|
||||
}
|
||||
```
|
||||
|
||||
## Custom Authorization Code
|
||||
|
||||
HTTP requests require an authorization code `<TOKEN>` for identification purposes. The administrator usually provides the authorization code, and it can be obtained simply by sending an ``HTTP GET`` request as follows:
|
||||
|
|
|
@ -58,6 +58,7 @@ And many more parameters.
|
|||
|
||||
- -a AUTHSTR: Authorization information to connect to the server.
|
||||
- -A: Obtain authorization information from username and password.
|
||||
- -B: Set BI mode , all outputs follow the format of BI tools for output if setting
|
||||
- -c CONFIGDIR: Specify the directory where configuration file exists. The default is `/etc/taos`, and the default name of the configuration file in this directory is `taos.cfg`
|
||||
- -C: Print the configuration parameters of `taos.cfg` in the default directory or specified by -c
|
||||
- -d DATABASE: Specify the database to use when connecting to the server
|
||||
|
|
|
@ -137,17 +137,10 @@ port = 6041
|
|||
username = "root"
|
||||
password = "taosdata"
|
||||
|
||||
# set taosAdapter to monitor
|
||||
[taosAdapter]
|
||||
address = ["127.0.0.1:6041","192.168.1.95:6041"]
|
||||
|
||||
[metrics]
|
||||
# monitoring metric prefix
|
||||
prefix = "taos"
|
||||
|
||||
# cluster data identifier
|
||||
cluster = "production"
|
||||
|
||||
# database to store monitoring data
|
||||
database = "log"
|
||||
|
||||
|
@ -157,6 +150,19 @@ tables = ["normal_table"]
|
|||
# database options for db storing metrics data
|
||||
[metrics.databaseoptions]
|
||||
cachemodel = "none"
|
||||
|
||||
[environment]
|
||||
# Whether running in cgroup.
|
||||
incgroup = false
|
||||
|
||||
[log]
|
||||
# rotation file num
|
||||
rotationCount = 5
|
||||
# rotation on time
|
||||
rotationTime = "24h"
|
||||
# rotation on file size (bytes)
|
||||
rotationSize = 100000000
|
||||
|
||||
```
|
||||
|
||||
### Obtain Monitoring Metrics
|
||||
|
@ -169,16 +175,16 @@ taosKeeper records monitoring metrics generated by TDengine in a specified datab
|
|||
$ taos
|
||||
# the log database is used in this example
|
||||
> use log;
|
||||
> select * from cluster_info limit 1;
|
||||
> select * from taosd_cluster_info limit 1;
|
||||
```
|
||||
|
||||
Example result set:
|
||||
|
||||
```shell
|
||||
ts | first_ep | first_ep_dnode_id | version | master_uptime | monitor_interval | dbs_total | tbs_total | stbs_total | dnodes_total | dnodes_alive | mnodes_total | mnodes_alive | vgroups_total | vgroups_alive | vnodes_total | vnodes_alive | connections_total | protocol | cluster_id |
|
||||
===============================================================================================================================================================================================================================================================================================================================================================================
|
||||
2022-08-16 17:37:01.629 | hlb:6030 | 1 | 3.0.0.0 | 0.27250 | 15 | 2 | 27 | 38 | 1 | 1 | 1 | 1 | 4 | 4 | 4 | 4 | 14 | 1 | 5981392874047724755 |
|
||||
Query OK, 1 rows in database (0.036162s)
|
||||
_ts | cluster_uptime | dbs_total | tbs_total | stbs_total | vgroups_total | vgroups_alive | vnodes_total | vnodes_alive | mnodes_total | mnodes_alive | connections_total | topics_total | streams_total | dnodes_total | dnodes_alive | grants_expire_time | grants_timeseries_used | grants_timeseries_total | cluster_id |
|
||||
===================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================
|
||||
2024-06-04 03:03:34.341 | 0.000000000000000 | 2.000000000000000 | 1.000000000000000 | 4.000000000000000 | 4.000000000000000 | 4.000000000000000 | 4.000000000000000 | 4.000000000000000 | 1.000000000000000 | 1.000000000000000 | 2.000000000000000 | 0.000000000000000 | 0.000000000000000 | 1.000000000000000 | 1.000000000000000 | 0.000000000000000 | 3.000000000000000 | 0.000000000000000 | 554014120921134497 |
|
||||
Query OK, 1 row(s) in set (0.001652s)
|
||||
```
|
||||
|
||||
#### Export Monitoring Metrics
|
||||
|
@ -192,19 +198,22 @@ Sample result set (excerpt):
|
|||
```shell
|
||||
# HELP taos_cluster_info_connections_total
|
||||
# TYPE taos_cluster_info_connections_total counter
|
||||
taos_cluster_info_connections_total{cluster_id="5981392874047724755"} 16
|
||||
taos_cluster_info_connections_total{cluster_id="554014120921134497"} 8
|
||||
# HELP taos_cluster_info_dbs_total
|
||||
# TYPE taos_cluster_info_dbs_total counter
|
||||
taos_cluster_info_dbs_total{cluster_id="5981392874047724755"} 2
|
||||
taos_cluster_info_dbs_total{cluster_id="554014120921134497"} 2
|
||||
# HELP taos_cluster_info_dnodes_alive
|
||||
# TYPE taos_cluster_info_dnodes_alive counter
|
||||
taos_cluster_info_dnodes_alive{cluster_id="5981392874047724755"} 1
|
||||
taos_cluster_info_dnodes_alive{cluster_id="554014120921134497"} 1
|
||||
# HELP taos_cluster_info_dnodes_total
|
||||
# TYPE taos_cluster_info_dnodes_total counter
|
||||
taos_cluster_info_dnodes_total{cluster_id="5981392874047724755"} 1
|
||||
taos_cluster_info_dnodes_total{cluster_id="554014120921134497"} 1
|
||||
# HELP taos_cluster_info_first_ep
|
||||
# TYPE taos_cluster_info_first_ep gauge
|
||||
taos_cluster_info_first_ep{cluster_id="5981392874047724755",value="hlb:6030"} 1
|
||||
taos_cluster_info_first_ep{cluster_id="554014120921134497",value="tdengine:6030"} 1
|
||||
# HELP taos_cluster_info_first_ep_dnode_id
|
||||
# TYPE taos_cluster_info_first_ep_dnode_id counter
|
||||
taos_cluster_info_first_ep_dnode_id{cluster_id="554014120921134497"} 1
|
||||
```
|
||||
|
||||
### check\_health
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
---
|
||||
title: Graphic User Interface
|
||||
sidebar_label: Taos-Explorer
|
||||
description: User guide about taosExplorer
|
||||
---
|
||||
|
||||
taos-explorer is a web service which provides GUI based interactive database management tool.
|
||||
|
||||
## Install
|
||||
|
||||
taos-explorer is delivered in the TDengine server package since version 3.3.0.0. After installing TDengine server, you will get the `taos-explorer` service.
|
||||
|
||||
## Configure
|
||||
|
||||
The configuration file of `taos-explorer` service is `/etc/taos/explorer.toml` on Linux platform, the key items in the configuration are like below:
|
||||
|
||||
``` toml
|
||||
port = 6060
|
||||
cluster = "http://localhost:6041"
|
||||
```
|
||||
|
||||
The description of these two parameters:
|
||||
|
||||
- port:taos-explorer service port
|
||||
- cluster:The end point of the TDengine cluster for the taos-explorer to manage. It supports only websocket connection, so this address is actually the end point of `taosAdapter` service in the TDengine cluster.
|
||||
|
||||
## Start & Stop
|
||||
|
||||
Before starting the service, please first make sure the configuration is correct, and the TDengine cluster (majorly including `taosd` and `taosAdapter` services) are already alive and working well.
|
||||
|
||||
### Linux
|
||||
|
||||
On Linux system you can use `systemctl` to manage the service as below:
|
||||
|
||||
- Start the service: `systemctl start taos-explorer`
|
||||
|
||||
- Stop the service: `systemctl stop taos-explorer`
|
||||
|
||||
- Restart the service: `systemctl restart taos-explorer`
|
||||
|
||||
- Check service status: `systemctl status taos-explorer`
|
||||
|
||||
## Register & Logon
|
||||
|
||||
### Register
|
||||
|
||||
After installing, configuring and starting, you can use your browser to access taos-explorer using address `http://ip:6060`. At this time, if you have not registered before, the registering page will first show up. You need to enter your valid enterprise email, receive the activation code, then input the code. Congratulations, you have registered successfully.
|
||||
|
||||
### Logon
|
||||
|
||||
After registering, you can use your user name and corresponding password in the database system to logon. The default username is `root`, but you can change it to use another one. After loggin into the system, you can view or manage databases, create super tables, create child tables, or view the data in the database.
|
||||
|
||||
There are some functionalities only available to enterprise users, you can view and experience but can't really use them.
|
|
@ -4,33 +4,43 @@ title: Power BI
|
|||
description: Use PowerBI and TDengine to analyze time series data
|
||||
---
|
||||
|
||||
## Introduction
|
||||
# Tools - Power BI
|
||||
|
||||
With TDengine ODBC driver, PowerBI can access time series data stored in TDengine. You can import tag data, original time series data, or aggregated data into PowerBI from TDengine, to create reports or dashboard without any coding effort.
|
||||

|
||||
|
||||
## Steps
|
||||

|
||||
[Power BI](https://powerbi.microsoft.com/) is a business analytics tool provided by Microsoft. With TDengine ODBC driver, PowerBI can access time series data stored in the TDengine. You can import tag data, original time series data, or aggregated data into Power BI from a TDengine, to create reports or dashboard without any coding effort.
|
||||
|
||||
### Prerequisites
|
||||
### Prerequisite
|
||||
1. TDengine server software is installed and running.
|
||||
2. Power BI Desktop has been installed and running (If not, please download and install the latest Windows X64 version from [PowerBI](https://www.microsoft.com/zh-cn/download/details.aspx?id=58494) ).
|
||||
|
||||
1. TDengine server has been installed and running well.
|
||||
2. Power BI Desktop has been installed and running. (If not, please download and install latest Windows X64 version from [PowerBI](https://www.microsoft.com/download/details.aspx?id=58494).
|
||||
### Install ODBC connector
|
||||
1. Only support Windows operation system. And you need to install [VC Runtime Library](https://learn.microsoft.com/zh-cn/cpp/windows/latest-supported-vc-redist?view=msvc-170) first. If already installed, please ignore this step.
|
||||
2. Install [TDengine Windows client installation package](https://docs.taosdata.com/get-started/package/).
|
||||
|
||||
### Configure ODBC DataSource
|
||||
1. Click the "Start" Menu, and Search for "ODBC", and choose "ODBC Data Source (64-bit)" (Note: Don't choose 32-bit).
|
||||
2. Select the "User DSN" tab, and click "Add" button to enter the page for "Create Data Source".
|
||||
3. Choose the data source to be added, here we choose "TDengine" and click "Finish", and enter the configuration page for "TDengine ODBC Data Source", fill in required fields as the following:
|
||||
|
||||
## Install Driver
|
||||
  [DSN]:       Data Source Name, required field, such as "MyTDengine"
|
||||
|
||||
Depending on your TDengine server version, download appropriate version of TDengine client package from TDengine website [Download Link](../../get-started/package/), or TDengine explorer if you are using a local TDengine cluster. Install the TDengine client package on same Windows machine where PowerBI is running.
|
||||
|
||||
### Configure Data Source
|
||||
|
||||
Please refer to [ODBC](../../client-libraries/odbc) to configure TDengine ODBC Driver with WebSocket connection.
|
||||
  [URL]:        taos://localhost:6041
|
||||
|
||||
  [Database]:     optional field, the default database to access, such as "test"
|
||||
|
||||
  [UserID]:      Enter the user name. If this parameter is not specified, the user name is root by default
|
||||
|
||||
  [Password]:     Enter the user password. If not, the default is taosdata
|
||||
|
||||
4. Click "Test Connection" to test whether the data source can be connectted; if successful, it will prompt "Successfully connected to taos://root:taosdata@localhost:6041".
|
||||
|
||||
### Import Data from TDengine to Power BI
|
||||
|
||||
1. Open Power BI and logon, add data source following steps "Home Page" -> "Get Data" -> "Others" -> "ODBC" -> "Connect"
|
||||
|
||||
2. Choose data source name, connect to configured data source, go to the nativator, browse tables of the selected database and load data
|
||||
|
||||
1. Open Power BI and logon, add data source following steps "Home" -> "Get data" -> "Other" -> "ODBC" -> "Connect".
|
||||
2. Choose the created data source name, such as "MyTDengine", then click "OK" button to open the "ODBC Driver" dialog. In the dialog, select "Default or Custom" left menu and then click "Connect" button to connect to the configured data source. After go to the "Nativator", browse tables of the selected database and load data.
|
||||
3. If you want to input some specific SQL, click "Advanced Options", and input your SQL in the open dialogue box and load the data.
|
||||
|
||||
|
||||
|
@ -49,17 +59,9 @@ To better use Power BI to analyze the data stored in TDengine, you need to under
|
|||
4. Correlation: Indicates how to correlate data. Dimentions and Metrics can be correlated by tbname, dates and metrics can be correlated by date. All these can cooperate to form visual reports.
|
||||
|
||||
### Example - Meters
|
||||
|
||||
TDengine has its own specific data model, which uses supertable as template and creates a specific table for each device. Each table can have maximum 4,096 data columns and 128 tags. In the example of meters, assume each meter generates one record per second, then there will be 86,400 records each day and 31,536,000 records every year, then only 1,000 meters will occupy 500GB disk space. So, the common usage of Power BI should be mapping tags to dimention columns, mapping the aggregation of data columns to metric columns, to provide indicators for decision makers.
|
||||
|
||||
1. Import Dimentions
|
||||
|
||||
Import the tags of tables in PowerBI, and name as "tags", the SQL is like `select distinct tbname, groupid, location from test.meters;`.
|
||||
|
||||
2. Import Metrics
|
||||
|
||||
In Power BI, import the average current, average voltage, average phase with 1 hour window, and name it as "data", the SQL is like `select tbname, _wstart ws, avg(current), avg(voltage), avg(phase) from test.meters PARTITION by tbname interval(1h)` .
|
||||
|
||||
3. Correlate Dimentions and Metrics
|
||||
|
||||
In Power BI, open model view, correlate "tags" and "data", and set "tabname" as the correlation column, then you can use the data in histogram, pie chart, etc. For more information about building visual reports in PowerBI, please refer to [Power BI](https://learn.microsoft.com/power-bi/)。
|
||||
TDengine has its own specific data model, which uses supertable as template and creates a specific table for each device. Each table can have maximum 4,096 data columns and 128 tags. In [the example of meters](https://docs.taosdata.com/concept/) , assume each meter generates one record per second, then there will be 86,400 records each day and 31,536,000 records every year, then only 1,000 meters will occupy 500GB disk space. So, the common usage of Power BI should be mapping tags to dimension columns, mapping the aggregation of data columns to metric columns, to provide indicators for decision makers.
|
||||
1. Import Dimensions: Import the tags of tables in PowerBI, and name as "tags", the SQL is as the following:
|
||||
`select distinct tbname, groupid, location from test.meters;`
|
||||
2. Import Metrics: In Power BI, import the average current, average voltage, average phase with 1 hour window, and name it as "data", the SQL is as the following:
|
||||
`select tbname, _wstart ws, avg(current), avg(voltage), avg(phase) from test.meters PARTITION by tbname interval(1h)` ;
|
||||
3. Correlate Dimensions and Metrics: In Power BI, open model view, correlate "tags" and "data", and set "tabname" as the correlation column, then you can use the data in histogram, pie chart, etc. For more information about building visual reports in PowerBI, please refer to [Power BI](https://learn.microsoft.com/zh-cn/power-bi/).
|
|
@ -0,0 +1,64 @@
|
|||
---
|
||||
sidebar_label: Yonghong BI
|
||||
title: Yonghong BI
|
||||
description: Use YonghongBI and TDengine to analyze time series data
|
||||
---
|
||||
|
||||
# Tools - Yonghong BI
|
||||
|
||||

|
||||
|
||||
[Yonghong one-stop big data BI platform](https://www.yonghongtech.com/)to provide enterprises of all sizes with flexible and easy-to-use whole-business chain big data analysis solutions, so that every user can use this platform to easily discover the value of big data and obtain deep insight. TDengine can be added to Yonghong BI as a data source via a JDBC connector. Once the data source is configured, Yonghong BI can read data from TDengine and provide functions such as data presentation, analysis and prediction.
|
||||
|
||||
### Prerequisite
|
||||
|
||||
1. Yonghong Desktop Basic is installed and running (if not,please go to [official download page of Yonghong Technology](https://www.yonghongtech.com/cp/desktop/) download).
|
||||
2. The TDengine is installed and running, and ensure that the taosadapter service is started on the TDengine server side.
|
||||
|
||||
### Install JDBC Connector
|
||||
|
||||
Go to [maven.org](https://central.sonatype.com/artifact/com.taosdata.jdbc/taos-jdbcdriver/versions) download the latest TDengine JDBC connector (current version [3.2.7](https://repo1.maven.org/maven2/com/taosdata/jdbc/taos-jdbcdriver/3.2.7/taos-jdbcdriver-3.2.7-dist.jar)) and install it on the machine where the BI tool is running.
|
||||
|
||||
### Configure JDBC DataSource
|
||||
|
||||
1. In the Yonghong Desktop BI tool, click "Add data source" and select the "GENERIC" type in the SQL data source.
|
||||
2. Click "Select Custom Driver", in the "Driver Management" dialog box, click "+" next to "Driver List", enter the name "MyTDengine". Then click the "upload file" button to upload just download TDengine JDBC connector file "taos-jdbcdriver-3.2.7-dist.jar", and select "com.taosdata.jdbc.rs.RestfulDriver" drive, Finally, click the "OK" button to complete the driver addition.
|
||||
3. Then copy the following into the "URL" field:
|
||||
```
|
||||
jdbc:TAOS-RS://localhost:6041?user=root&password=taosdata
|
||||
```
|
||||
4. Then select "No identity Authentication" under "Authentication Mode".
|
||||
5. In the advanced Settings of the data source, change the value of the Quote symbol to the backquote "`".
|
||||
6. Click "Test connection" and the dialog box "Test success" will pop up. Click the "Save" button and enter "tdengine" to save the TDengine data source.
|
||||
|
||||
### Create TDengine datasets
|
||||
|
||||
1. Click "Add Data Set" in the BI tool, expand the data source you just created, and browse the super table in TDengine.
|
||||
2. You can load all the data of the super table into the BI tool, or you can import some data through custom SQL statements.
|
||||
3. When "Computation in Database" is selected, the BI tool will no longer cache TDengine timing data and will send SQL requests to TDengine for direct processing when processing queries.
|
||||
|
||||
When data is imported, the BI tool automatically sets the numeric type to the "metric" column and the text type to the "dimension" column. In TDengine super tables, ordinary columns are used as data metrics and label columns are used as data dimensions, so you may need to change the properties of some columns when you create a dataset. On the basis of supporting standard SQL, TDengine also provides a series of special query syntax to meet the requirements of time series business scenarios, such as data segmentation query, window segmentation query, etc., for [TDengine Specialized Queries](https://docs.taosdata.com/taos-sql/distinguished/) .By using these featured queries, BI tools can greatly improve data access speed and reduce network transmission bandwidth when they send SQL queries to TDengine databases.
|
||||
|
||||
In BI tools, you can create "parameters" and use them in SQL statements, which can be dynamically executed manually and periodically to achieve a visual report refresh effect.The following SQL statement:
|
||||
|
||||
```sql
|
||||
select _wstart ws, count(*) cnt from supertable where tbname=?{metric} and ts >= ?{from} and ts < ?{to} interval(?{interval})
|
||||
```
|
||||
|
||||
Data can be read in real time from TDengine, where:
|
||||
|
||||
- `_wstart`: Indicates the start time of the time window.
|
||||
- `count(*)`: Indicates the aggregate value in the time window.
|
||||
- `?{interval}`: Indicates that the parameter interval is introduced into the SQL statement. When the BI tool queries data, it assigns a value to the parameter interval. If the value is 1m, the sampling data is reduced based on a 1-minute time window.
|
||||
- `?{metric}`: This parameter is used to specify the name of the data table to be queried. When the ID of a drop-down parameter component is set as metric in the BI tool, the selected items of the drop-down parameter component are bound to this parameter to achieve dynamic selection.
|
||||
- `?{from}` `?{to}`:These two parameters are used to represent the time range of the query data set and can be bound with the Text Parameter Component.
|
||||
|
||||
You can modify the data type, data range, and default values of parameters in the "Edit Parameters" dialog box of the BI tool, and dynamically set the values of these parameters in the "Visual Report".
|
||||
|
||||
### Create a visual report
|
||||
|
||||
1. Click "Make Report" in Yonghong BI tool to create a canvas.
|
||||
2. Drag visual components, such as Table Components, onto the canvas.
|
||||
3. Select the data set to be bound in the Data Set sidebar, and bind Dimensions and Measures in the data column to Table Components as needed.
|
||||
4. Click "Save" to view the report.
|
||||
5. For more information about Yonghong BI tools, please consult them [Help document](https://www.yonghongtech.com/help/Z-Suite/10.0/ch/).
|
After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 36 KiB |
After Width: | Height: | Size: 14 KiB |
|
@ -90,7 +90,7 @@ Through TAOSC caching mechanism, mnode needs to be accessed only when a table is
|
|||
|
||||
### Storage Model
|
||||
|
||||
The data stored by TDengine includes collected time-series data, metadata and tag data related to database and tablesetc. All of the data is specifically divided into three parts:
|
||||
The data stored by TDengine includes collected time-series data, metadata and tag data related to database and tables, etc. All of the data is specifically divided into three parts:
|
||||
|
||||
- Time-series data: stored in vnode and composed of data, head and last files. Normally the amount of time series data is very huge and query amount depends on the application scenario. Out-of-order writing is allowed. By adopting the model with **one table for each data collection point**, the data of a given time period is continuously stored, and the writing against one single table is a simple appending operation. Multiple records can be read at one time, thus ensuring the best performance for both insert and query operations of a single data collection point.
|
||||
- Table Metadata: table meta data includes tags and table schema and is stored in meta file in each vnode. CRUD can be operated on table metadata. There is a specific record for each table, so the amount of table meta data depends on the number of tables. Table meta data is stored in LRU model and supports index for tag data. TDengine can support multiple queries in parallel. As long as the memory resource is enough, meta data is all stored in memory for quick access. The filtering on tens of millions of tags can be finished in a few milliseconds. Even though when the memory resource is not sufficient, TDengine can still perform high speed query on tens of millions of tables.
|
||||
|
|
|
@ -4,12 +4,26 @@ sidebar_label: TDengine
|
|||
description: This document provides download links for all released versions of TDengine 3.0.
|
||||
---
|
||||
|
||||
## TDengine Version Rules
|
||||
|
||||
TDengine version number consists of 4 numbers separated by `.`, defined as below:
|
||||
- `[Major+].[Major].[Feature].[Maintenance]`
|
||||
- `Major+`: Significant rearchitecture release, can't be upgraded from an old version with different `Major+` number. If you have such a need, please contact TDengine support team.
|
||||
- `Major`: Important new feature release, can't be rolling upgraded from old version with different `Major` number, and can't be rolled back after upgrading. For example, after upgrading from `3.2.3.0` to `3.3.0.0`, you can't roll back to `3.2.3.0`.
|
||||
- `Feature`:New feature release, can't be rolling upgraded from an old version with different `Feature` number, but can be rolled back after upgrading. For example, after upgrading from `3.3.0.0` to `3.3.1.0`, you can roll back to `3.3.0.0`. The client driver (libtaos.so) must be upgraded to same version as the server side (taosd).
|
||||
- `Maintenance`: Maintenance release, no new features but only bug fixings, can be rolling upgraded from an old version with only `Maintenance` number different, and can be rolled back after upgrading.
|
||||
- `Rolling Upgrade`: For a cluster consisting of three or more dnodes with three replica enabled, you can upgrade one dnode each time by stopping it, upgrading it, and then restarting it, repeat this process to upgrade the whole cluster. During this period, the cluster is still in service. If rolling upgrade is not supported based on the above version number rules, you need to first stop the whole cluster, upgrade all dndoes, and restart all dnodes after upgrading. During this period, the cluster is out of service.
|
||||
|
||||
TDengine 3.x installation packages can be downloaded at the following links:
|
||||
|
||||
For TDengine 2.x installation packages by version, please visit [here](https://tdengine.com/downloads/historical/).
|
||||
|
||||
import Release from "/components/ReleaseV3";
|
||||
|
||||
## 3.3.2.0
|
||||
|
||||
<Release type="tdengine" version="3.3.2.0" />
|
||||
|
||||
## 3.3.1.0
|
||||
|
||||
<Release type="tdengine" version="3.3.1.0" />
|
||||
|
|
|
@ -0,0 +1,113 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/taosdata/driver-go/v3/af"
|
||||
"github.com/taosdata/driver-go/v3/af/tmq"
|
||||
tmqcommon "github.com/taosdata/driver-go/v3/common/tmq"
|
||||
)
|
||||
|
||||
func main() {
|
||||
db, err := af.Open("", "root", "taosdata", "", 0)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer db.Close()
|
||||
_, err = db.Exec("create database if not exists power WAL_RETENTION_PERIOD 86400")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
_, err = db.Exec("CREATE STABLE IF NOT EXISTS power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
_, err = db.Exec("create table if not exists power.d001 using power.meters tags(1,'location')")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
// ANCHOR: create_topic
|
||||
_, err = db.Exec("CREATE TOPIC IF NOT EXISTS topic_meters AS SELECT ts, current, voltage, phase, groupid, location FROM power.meters")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
// ANCHOR_END: create_topic
|
||||
// ANCHOR: create_consumer
|
||||
consumer, err := tmq.NewConsumer(&tmqcommon.ConfigMap{
|
||||
"group.id": "test",
|
||||
"auto.offset.reset": "latest",
|
||||
"td.connect.ip": "127.0.0.1",
|
||||
"td.connect.user": "root",
|
||||
"td.connect.pass": "taosdata",
|
||||
"td.connect.port": "6030",
|
||||
"client.id": "test_tmq_client",
|
||||
"enable.auto.commit": "false",
|
||||
"msg.with.table.name": "true",
|
||||
})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
// ANCHOR_END: create_consumer
|
||||
// ANCHOR: poll_data
|
||||
go func() {
|
||||
for {
|
||||
_, err = db.Exec("insert into power.d001 values (now, 1.1, 220, 0.1)")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
time.Sleep(time.Millisecond * 100)
|
||||
}
|
||||
}()
|
||||
|
||||
err = consumer.Subscribe("topic_meters", nil)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
for i := 0; i < 5; i++ {
|
||||
ev := consumer.Poll(500)
|
||||
if ev != nil {
|
||||
switch e := ev.(type) {
|
||||
case *tmqcommon.DataMessage:
|
||||
fmt.Printf("get message:%v\n", e)
|
||||
case tmqcommon.Error:
|
||||
fmt.Fprintf(os.Stderr, "%% Error: %v: %v\n", e.Code(), e)
|
||||
panic(e)
|
||||
}
|
||||
consumer.Commit()
|
||||
}
|
||||
}
|
||||
// ANCHOR_END: poll_data
|
||||
// ANCHOR: consumer_seek
|
||||
partitions, err := consumer.Assignment()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for i := 0; i < len(partitions); i++ {
|
||||
fmt.Println(partitions[i])
|
||||
err = consumer.Seek(tmqcommon.TopicPartition{
|
||||
Topic: partitions[i].Topic,
|
||||
Partition: partitions[i].Partition,
|
||||
Offset: 0,
|
||||
}, 0)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
partitions, err = consumer.Assignment()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
// ANCHOR_END: consumer_seek
|
||||
for i := 0; i < len(partitions); i++ {
|
||||
fmt.Println(partitions[i])
|
||||
}
|
||||
// ANCHOR: consumer_close
|
||||
err = consumer.Close()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
// ANCHOR_END: consumer_close
|
||||
}
|
|
@ -0,0 +1,115 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/taosdata/driver-go/v3/common"
|
||||
tmqcommon "github.com/taosdata/driver-go/v3/common/tmq"
|
||||
_ "github.com/taosdata/driver-go/v3/taosRestful"
|
||||
"github.com/taosdata/driver-go/v3/ws/tmq"
|
||||
)
|
||||
|
||||
func main() {
|
||||
db, err := sql.Open("taosRestful", "root:taosdata@http(localhost:6041)/")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer db.Close()
|
||||
_, err = db.Exec("create database if not exists power WAL_RETENTION_PERIOD 86400")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
_, err = db.Exec("CREATE STABLE IF NOT EXISTS power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
_, err = db.Exec("create table if not exists power.d001 using power.meters tags(1,'location')")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
// ANCHOR: create_topic
|
||||
_, err = db.Exec("CREATE TOPIC IF NOT EXISTS topic_meters AS SELECT ts, current, voltage, phase, groupid, location FROM power.meters")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
// ANCHOR_END: create_topic
|
||||
// ANCHOR: create_consumer
|
||||
consumer, err := tmq.NewConsumer(&tmqcommon.ConfigMap{
|
||||
"ws.url": "ws://127.0.0.1:6041",
|
||||
"ws.message.channelLen": uint(0),
|
||||
"ws.message.timeout": common.DefaultMessageTimeout,
|
||||
"ws.message.writeWait": common.DefaultWriteWait,
|
||||
"td.connect.user": "root",
|
||||
"td.connect.pass": "taosdata",
|
||||
"group.id": "example",
|
||||
"client.id": "example_consumer",
|
||||
"auto.offset.reset": "latest",
|
||||
})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
// ANCHOR_END: create_consumer
|
||||
// ANCHOR: poll_data
|
||||
go func() {
|
||||
for {
|
||||
_, err = db.Exec("insert into power.d001 values (now, 1.1, 220, 0.1)")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
time.Sleep(time.Millisecond * 100)
|
||||
}
|
||||
}()
|
||||
|
||||
err = consumer.Subscribe("topic_meters", nil)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
for i := 0; i < 5; i++ {
|
||||
ev := consumer.Poll(500)
|
||||
if ev != nil {
|
||||
switch e := ev.(type) {
|
||||
case *tmqcommon.DataMessage:
|
||||
fmt.Printf("get message:%v\n", e)
|
||||
case tmqcommon.Error:
|
||||
fmt.Fprintf(os.Stderr, "%% Error: %v: %v\n", e.Code(), e)
|
||||
panic(e)
|
||||
}
|
||||
consumer.Commit()
|
||||
}
|
||||
}
|
||||
// ANCHOR_END: poll_data
|
||||
// ANCHOR: consumer_seek
|
||||
partitions, err := consumer.Assignment()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for i := 0; i < len(partitions); i++ {
|
||||
fmt.Println(partitions[i])
|
||||
err = consumer.Seek(tmqcommon.TopicPartition{
|
||||
Topic: partitions[i].Topic,
|
||||
Partition: partitions[i].Partition,
|
||||
Offset: 0,
|
||||
}, 0)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
partitions, err = consumer.Assignment()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
// ANCHOR_END: consumer_seek
|
||||
for i := 0; i < len(partitions); i++ {
|
||||
fmt.Println(partitions[i])
|
||||
}
|
||||
// ANCHOR: consumer_close
|
||||
err = consumer.Close()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
// ANCHOR_END: consumer_close
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"github.com/taosdata/driver-go/v3/common"
|
||||
_ "github.com/taosdata/driver-go/v3/taosSql"
|
||||
)
|
||||
|
||||
func main() {
|
||||
var taosDSN = "root:taosdata@tcp(localhost:6030)/"
|
||||
taos, err := sql.Open("taosSql", taosDSN)
|
||||
if err != nil {
|
||||
log.Fatalln("failed to connect TDengine, err:", err)
|
||||
}
|
||||
defer taos.Close()
|
||||
// ANCHOR: create_db_and_table
|
||||
_, err = taos.Exec("CREATE DATABASE if not exists power")
|
||||
if err != nil {
|
||||
log.Fatalln("failed to create database, err:", err)
|
||||
}
|
||||
_, err = taos.Exec("CREATE STABLE IF NOT EXISTS power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))")
|
||||
if err != nil {
|
||||
log.Fatalln("failed to create stable, err:", err)
|
||||
}
|
||||
// ANCHOR_END: create_db_and_table
|
||||
// ANCHOR: insert_data
|
||||
affected, err := taos.Exec("INSERT INTO " +
|
||||
"power.d1001 USING power.meters TAGS(2,'California.SanFrancisco') " +
|
||||
"VALUES " +
|
||||
"(NOW + 1a, 10.30000, 219, 0.31000) " +
|
||||
"(NOW + 2a, 12.60000, 218, 0.33000) " +
|
||||
"(NOW + 3a, 12.30000, 221, 0.31000) " +
|
||||
"power.d1002 USING power.meters TAGS(3, 'California.SanFrancisco') " +
|
||||
"VALUES " +
|
||||
"(NOW + 1a, 10.30000, 218, 0.25000) ")
|
||||
if err != nil {
|
||||
log.Fatalln("failed to insert data, err:", err)
|
||||
}
|
||||
log.Println("affected rows:", affected)
|
||||
// ANCHOR_END: insert_data
|
||||
// ANCHOR: query_data
|
||||
rows, err := taos.Query("SELECT * FROM power.meters")
|
||||
if err != nil {
|
||||
log.Fatalln("failed to select from table, err:", err)
|
||||
}
|
||||
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
var (
|
||||
ts time.Time
|
||||
current float32
|
||||
voltage int
|
||||
phase float32
|
||||
groupId int
|
||||
location string
|
||||
)
|
||||
err := rows.Scan(&ts, ¤t, &voltage, &phase, &groupId, &location)
|
||||
if err != nil {
|
||||
log.Fatalln("scan error:\n", err)
|
||||
return
|
||||
}
|
||||
log.Println(ts, current, voltage, phase, groupId, location)
|
||||
}
|
||||
// ANCHOR_END: query_data
|
||||
// ANCHOR: with_reqid
|
||||
ctx := context.WithValue(context.Background(), common.ReqIDKey, common.GetReqID())
|
||||
_, err = taos.ExecContext(ctx, "CREATE DATABASE IF NOT EXISTS power")
|
||||
if err != nil {
|
||||
log.Fatalln("failed to create database, err:", err)
|
||||
}
|
||||
// ANCHOR_END: with_reqid
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/taosdata/driver-go/v3/af"
|
||||
)
|
||||
|
||||
const LineDemo = "meters,groupid=2,location=California.SanFrancisco current=10.3000002f64,voltage=219i32,phase=0.31f64 1626006833639000000"
|
||||
|
||||
const TelnetDemo = "stb0_0 1707095283260 4 host=host0 interface=eth0"
|
||||
|
||||
const JsonDemo = "{\"metric\": \"meter_current\",\"timestamp\": 1626846400,\"value\": 10.3, \"tags\": {\"groupid\": 2, \"location\": \"California.SanFrancisco\", \"id\": \"d1001\"}}"
|
||||
|
||||
func main() {
|
||||
conn, err := af.Open("localhost", "root", "taosdata", "", 6030)
|
||||
if err != nil {
|
||||
fmt.Println("fail to connect, err:", err)
|
||||
}
|
||||
defer conn.Close()
|
||||
_, err = conn.Exec("CREATE DATABASE IF NOT EXISTS power")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
_, err = conn.Exec("use power")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = conn.InfluxDBInsertLines([]string{LineDemo}, "ns")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = conn.OpenTSDBInsertTelnetLines([]string{TelnetDemo})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = conn.OpenTSDBInsertJsonPayload(JsonDemo)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"github.com/taosdata/driver-go/v3/common"
|
||||
_ "github.com/taosdata/driver-go/v3/taosWS"
|
||||
"github.com/taosdata/driver-go/v3/ws/schemaless"
|
||||
)
|
||||
|
||||
const LineDemo = "meters,groupid=2,location=California.SanFrancisco current=10.3000002f64,voltage=219i32,phase=0.31f64 1626006833639000000"
|
||||
|
||||
const TelnetDemo = "stb0_0 1707095283260 4 host=host0 interface=eth0"
|
||||
|
||||
const JsonDemo = "{\"metric\": \"meter_current\",\"timestamp\": 1626846400,\"value\": 10.3, \"tags\": {\"groupid\": 2, \"location\": \"California.SanFrancisco\", \"id\": \"d1001\"}}"
|
||||
|
||||
func main() {
|
||||
db, err := sql.Open("taosWS", "root:taosdata@ws(localhost:6041)/")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer db.Close()
|
||||
_, err = db.Exec("create database if not exists power")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
s, err := schemaless.NewSchemaless(schemaless.NewConfig("ws://localhost:6041", 1,
|
||||
schemaless.SetDb("power"),
|
||||
schemaless.SetReadTimeout(10*time.Second),
|
||||
schemaless.SetWriteTimeout(10*time.Second),
|
||||
schemaless.SetUser("root"),
|
||||
schemaless.SetPassword("taosdata"),
|
||||
schemaless.SetErrorHandler(func(err error) {
|
||||
log.Fatal(err)
|
||||
}),
|
||||
))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = s.Insert(LineDemo, schemaless.InfluxDBLineProtocol, "ns", 0, common.GetReqID())
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = s.Insert(TelnetDemo, schemaless.OpenTSDBTelnetLineProtocol, "ms", 0, common.GetReqID())
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = s.Insert(JsonDemo, schemaless.OpenTSDBJsonFormatProtocol, "ms", 0, common.GetReqID())
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/taosdata/driver-go/v3/af"
|
||||
"github.com/taosdata/driver-go/v3/common"
|
||||
"github.com/taosdata/driver-go/v3/common/param"
|
||||
)
|
||||
|
||||
const (
|
||||
NumOfSubTable = 10
|
||||
NumOfRow = 10
|
||||
)
|
||||
|
||||
func main() {
|
||||
prepare()
|
||||
db, err := af.Open("", "root", "taosdata", "power", 0)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer db.Close()
|
||||
stmt := db.InsertStmt()
|
||||
defer stmt.Close()
|
||||
err = stmt.Prepare("INSERT INTO ? USING meters TAGS(?,?) VALUES (?,?,?,?)")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for i := 1; i <= NumOfSubTable; i++ {
|
||||
tags := param.NewParam(2).AddInt(i).AddBinary([]byte("location"))
|
||||
err = stmt.SetTableNameWithTags("d_bind_"+strconv.Itoa(i), tags)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
now := time.Now()
|
||||
params := make([]*param.Param, 4)
|
||||
params[0] = param.NewParam(NumOfRow)
|
||||
params[1] = param.NewParam(NumOfRow)
|
||||
params[2] = param.NewParam(NumOfRow)
|
||||
params[3] = param.NewParam(NumOfRow)
|
||||
for i := 0; i < NumOfRow; i++ {
|
||||
params[0].SetTimestamp(i, now.Add(time.Duration(i)*time.Second), common.PrecisionMilliSecond)
|
||||
params[1].SetFloat(i, float32(i))
|
||||
params[2].SetInt(i, i)
|
||||
params[3].SetFloat(i, float32(i))
|
||||
}
|
||||
paramTypes := param.NewColumnType(4).AddTimestamp().AddFloat().AddInt().AddFloat()
|
||||
err = stmt.BindParam(params, paramTypes)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = stmt.AddBatch()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = stmt.Execute()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
affected := stmt.GetAffectedRows()
|
||||
fmt.Println("affected rows:", affected)
|
||||
}
|
||||
}
|
||||
|
||||
func prepare() {
|
||||
db, err := af.Open("", "root", "taosdata", "", 0)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer db.Close()
|
||||
_, err = db.Exec("CREATE DATABASE IF NOT EXISTS power")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
_, err = db.Exec("CREATE STABLE IF NOT EXISTS power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,95 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/taosdata/driver-go/v3/common"
|
||||
"github.com/taosdata/driver-go/v3/common/param"
|
||||
_ "github.com/taosdata/driver-go/v3/taosRestful"
|
||||
"github.com/taosdata/driver-go/v3/ws/stmt"
|
||||
)
|
||||
|
||||
const (
|
||||
NumOfSubTable = 10
|
||||
NumOfRow = 10
|
||||
)
|
||||
|
||||
func main() {
|
||||
prepare()
|
||||
config := stmt.NewConfig("ws://127.0.0.1:6041", 0)
|
||||
config.SetConnectUser("root")
|
||||
config.SetConnectPass("taosdata")
|
||||
config.SetConnectDB("power")
|
||||
config.SetMessageTimeout(common.DefaultMessageTimeout)
|
||||
config.SetWriteWait(common.DefaultWriteWait)
|
||||
config.SetErrorHandler(func(connector *stmt.Connector, err error) {
|
||||
panic(err)
|
||||
})
|
||||
config.SetCloseHandler(func() {
|
||||
fmt.Println("stmt connector closed")
|
||||
})
|
||||
|
||||
connector, err := stmt.NewConnector(config)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
stmt, err := connector.Init()
|
||||
err = stmt.Prepare("INSERT INTO ? USING meters TAGS(?,?) VALUES (?,?,?,?)")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for i := 1; i <= NumOfSubTable; i++ {
|
||||
tags := param.NewParam(2).AddInt(i).AddBinary([]byte("location"))
|
||||
err = stmt.SetTableName("d_bind_" + strconv.Itoa(i))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = stmt.SetTags(tags, param.NewColumnType(2).AddInt().AddBinary(8))
|
||||
now := time.Now()
|
||||
params := make([]*param.Param, 4)
|
||||
params[0] = param.NewParam(NumOfRow)
|
||||
params[1] = param.NewParam(NumOfRow)
|
||||
params[2] = param.NewParam(NumOfRow)
|
||||
params[3] = param.NewParam(NumOfRow)
|
||||
for i := 0; i < NumOfRow; i++ {
|
||||
params[0].SetTimestamp(i, now.Add(time.Duration(i)*time.Second), common.PrecisionMilliSecond)
|
||||
params[1].SetFloat(i, float32(i))
|
||||
params[2].SetInt(i, i)
|
||||
params[3].SetFloat(i, float32(i))
|
||||
}
|
||||
paramTypes := param.NewColumnType(4).AddTimestamp().AddFloat().AddInt().AddFloat()
|
||||
err = stmt.BindParam(params, paramTypes)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = stmt.AddBatch()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = stmt.Exec()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
affected := stmt.GetAffectedRows()
|
||||
fmt.Println("affected rows:", affected)
|
||||
}
|
||||
}
|
||||
|
||||
func prepare() {
|
||||
db, err := sql.Open("taosRestful", "root:taosdata@http(localhost:6041)/")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer db.Close()
|
||||
_, err = db.Exec("CREATE DATABASE IF NOT EXISTS power")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
_, err = db.Exec("CREATE STABLE IF NOT EXISTS power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
const taos = require("@tdengine/websocket");
|
||||
|
||||
var host = null;
|
||||
for(var i = 2; i < global.process.argv.length; i++){
|
||||
var key = global.process.argv[i].split("=")[0];
|
||||
var value = global.process.argv[i].split("=")[1];
|
||||
if("host" == key){
|
||||
host = value;
|
||||
}
|
||||
}
|
||||
|
||||
if(host == null){
|
||||
console.log("Usage: node nodejsChecker.js host=<hostname> port=<port>");
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
let dbData = ["{\"metric\": \"meter_current\",\"timestamp\": 1626846402,\"value\": 10.3, \"tags\": {\"groupid\": 2, \"location\": \"California.SanFrancisco\", \"id\": \"d1001\"}}",
|
||||
"{\"metric\": \"meter_current\",\"timestamp\": 1626846403,\"value\": 10.3, \"tags\": {\"groupid\": 2, \"location\": \"California.SanFrancisco\", \"id\": \"d1002\"}}",
|
||||
"{\"metric\": \"meter_current\",\"timestamp\": 1626846404,\"value\": 10.3, \"tags\": {\"groupid\": 2, \"location\": \"California.SanFrancisco\", \"id\": \"d1003\"}}"]
|
||||
|
||||
async function createConnect() {
|
||||
let dsn = 'ws://' + host + ':6041'
|
||||
let conf = new taos.WSConfig(dsn);
|
||||
conf.setUser('root');
|
||||
conf.setPwd('taosdata');
|
||||
conf.setDb('power');
|
||||
return await taos.sqlConnect(conf);
|
||||
}
|
||||
|
||||
async function test() {
|
||||
let wsSql = null;
|
||||
let wsRows = null;
|
||||
let reqId = 0;
|
||||
try {
|
||||
wsSql = await createConnect()
|
||||
await wsSql.exec('CREATE DATABASE IF NOT EXISTS power KEEP 3650 DURATION 10 BUFFER 16 WAL_LEVEL 1;', reqId++);
|
||||
await wsSql.schemalessInsert([dbData], taos.SchemalessProto.OpenTSDBJsonFormatProtocol, taos.Precision.SECONDS, 0);
|
||||
}
|
||||
catch (err) {
|
||||
console.error(err.code, err.message);
|
||||
}
|
||||
finally {
|
||||
if (wsRows) {
|
||||
await wsRows.close();
|
||||
}
|
||||
if (wsSql) {
|
||||
await wsSql.close();
|
||||
}
|
||||
taos.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
test()
|
|
@ -0,0 +1,49 @@
|
|||
const taos = require("@tdengine/websocket");
|
||||
|
||||
let influxdbData = ["meters,location=California.LosAngeles,groupId=2 current=11.8,voltage=221,phase=0.28 1648432611249",
|
||||
"meters,location=California.LosAngeles,groupId=2 current=13.4,voltage=223,phase=0.29 1648432611250",
|
||||
"meters,location=California.LosAngeles,groupId=3 current=10.8,voltage=223,phase=0.29 1648432611249"];
|
||||
|
||||
let jsonData = ["{\"metric\": \"meter_current\",\"timestamp\": 1626846402,\"value\": 10.3, \"tags\": {\"groupid\": 2, \"location\": \"California.SanFrancisco\", \"id\": \"d1001\"}}",
|
||||
"{\"metric\": \"meter_current\",\"timestamp\": 1626846403,\"value\": 10.3, \"tags\": {\"groupid\": 2, \"location\": \"California.SanFrancisco\", \"id\": \"d1002\"}}",
|
||||
"{\"metric\": \"meter_current\",\"timestamp\": 1626846404,\"value\": 10.3, \"tags\": {\"groupid\": 2, \"location\": \"California.SanFrancisco\", \"id\": \"d1003\"}}"]
|
||||
|
||||
let telnetData = ["meters.current 1648432611249 10.3 location=California.SanFrancisco groupid=2",
|
||||
"meters.current 1648432611250 12.6 location=California.SanFrancisco groupid=2",
|
||||
"meters.current 1648432611249 10.8 location=California.LosAngeles groupid=3"];
|
||||
|
||||
async function createConnect() {
|
||||
let dsn = 'ws://localhost:6041'
|
||||
let conf = new taos.WSConfig(dsn);
|
||||
conf.setUser('root');
|
||||
conf.setPwd('taosdata');
|
||||
let wsSql = await taos.sqlConnect(conf);
|
||||
await wsSql.exec('CREATE DATABASE IF NOT EXISTS power KEEP 3650 DURATION 10 BUFFER 16 WAL_LEVEL 1;');
|
||||
await wsSql.exec('USE power');
|
||||
return wsSql;
|
||||
}
|
||||
|
||||
async function test() {
|
||||
let wsSql = null;
|
||||
let wsRows = null;
|
||||
let ttl = 0;
|
||||
try {
|
||||
wsSql = await createConnect()
|
||||
await wsSql.schemalessInsert(influxdbData, taos.SchemalessProto.InfluxDBLineProtocol, taos.Precision.MILLI_SECONDS, ttl);
|
||||
await wsSql.schemalessInsert(jsonData, taos.SchemalessProto.OpenTSDBJsonFormatProtocol, taos.Precision.SECONDS, ttl);
|
||||
await wsSql.schemalessInsert(telnetData, taos.SchemalessProto.OpenTSDBTelnetLineProtocol, taos.Precision.MILLI_SECONDS, ttl);
|
||||
}
|
||||
catch (err) {
|
||||
console.error(err.code, err.message);
|
||||
}
|
||||
finally {
|
||||
if (wsRows) {
|
||||
await wsRows.close();
|
||||
}
|
||||
if (wsSql) {
|
||||
await wsSql.close();
|
||||
}
|
||||
taos.destroy();
|
||||
}
|
||||
}
|
||||
test()
|
|
@ -0,0 +1,77 @@
|
|||
const taos = require("@tdengine/websocket");
|
||||
|
||||
var host = null;
|
||||
for(var i = 2; i < global.process.argv.length; i++){
|
||||
var key = global.process.argv[i].split("=")[0];
|
||||
var value = global.process.argv[i].split("=")[1];
|
||||
if("host" == key){
|
||||
host = value;
|
||||
}
|
||||
}
|
||||
|
||||
if(host == null){
|
||||
console.log("Usage: node nodejsChecker.js host=<hostname> port=<port>");
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
|
||||
async function createConnect() {
|
||||
let dsn = 'ws://' + host + ':6041'
|
||||
console.log(dsn)
|
||||
let conf = new taos.WSConfig(dsn);
|
||||
conf.setUser('root')
|
||||
conf.setPwd('taosdata')
|
||||
return await taos.sqlConnect(conf);
|
||||
}
|
||||
|
||||
async function test() {
|
||||
let wsSql = null;
|
||||
let wsRows = null;
|
||||
let reqId = 0;
|
||||
try {
|
||||
wsSql = await createConnect()
|
||||
let version = await wsSql.version();
|
||||
console.log(version);
|
||||
let taosResult = await wsSql.exec('SHOW DATABASES', reqId++);
|
||||
console.log(taosResult);
|
||||
|
||||
taosResult = await wsSql.exec('CREATE DATABASE IF NOT EXISTS power KEEP 3650 DURATION 10 BUFFER 16 WAL_LEVEL 1;', reqId++);
|
||||
console.log(taosResult);
|
||||
|
||||
taosResult = await wsSql.exec('USE power', reqId++);
|
||||
console.log(taosResult);
|
||||
|
||||
taosResult = await wsSql.exec('CREATE STABLE IF NOT EXISTS meters (_ts timestamp, current float, voltage int, phase float) TAGS (location binary(64), groupId int);', reqId++);
|
||||
console.log(taosResult);
|
||||
|
||||
taosResult = await wsSql.exec('DESCRIBE meters', reqId++);
|
||||
console.log(taosResult);
|
||||
|
||||
taosResult = await wsSql.exec('INSERT INTO d1001 USING meters (location, groupId) TAGS ("California.SanFrancisco", 3) VALUES (NOW, 10.2, 219, 0.32)', reqId++);
|
||||
console.log(taosResult);
|
||||
|
||||
wsRows = await wsSql.query('SELECT * FROM meters', reqId++);
|
||||
let meta = wsRows.getMeta();
|
||||
console.log("wsRow:meta:=>", meta);
|
||||
|
||||
while (await wsRows.next()) {
|
||||
let result = wsRows.getData();
|
||||
console.log('queryRes.Scan().then=>', result);
|
||||
}
|
||||
|
||||
}
|
||||
catch (err) {
|
||||
console.error(err.code, err.message);
|
||||
}
|
||||
finally {
|
||||
if (wsRows) {
|
||||
await wsRows.close();
|
||||
}
|
||||
if (wsSql) {
|
||||
await wsSql.close();
|
||||
}
|
||||
taos.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
test()
|
|
@ -0,0 +1,143 @@
|
|||
const taos = require("@tdengine/websocket");
|
||||
|
||||
// ANCHOR: createConnect
|
||||
async function createConnect() {
|
||||
let dsn = 'ws://localhost:6041';
|
||||
let conf = new taos.WSConfig(dsn);
|
||||
conf.setUser('root');
|
||||
conf.setPwd('taosdata');
|
||||
conf.setDb('power');
|
||||
return await taos.sqlConnect(conf);
|
||||
}
|
||||
// ANCHOR_END: createConnect
|
||||
|
||||
// ANCHOR: create_db_and_table
|
||||
async function createDbAndTable(wsSql) {
|
||||
let wsSql = null;
|
||||
try {
|
||||
wsSql = await createConnect();
|
||||
await wsSql.exec('CREATE DATABASE IF NOT EXISTS POWER ' +
|
||||
'KEEP 3650 DURATION 10 BUFFER 16 WAL_LEVEL 1;');
|
||||
|
||||
await wsSql.exec('USE power');
|
||||
|
||||
await wsSql.exec('CREATE STABLE IF NOT EXISTS meters ' +
|
||||
'(_ts timestamp, current float, voltage int, phase float) ' +
|
||||
'TAGS (location binary(64), groupId int);');
|
||||
|
||||
taosResult = await wsSql.exec('describe meters');
|
||||
console.log(taosResult);
|
||||
} catch (err) {
|
||||
|
||||
console.error(err.code, err.message);
|
||||
} finally {
|
||||
if (wsSql) {
|
||||
await wsSql.close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
// ANCHOR_END: create_db_and_table
|
||||
|
||||
// ANCHOR: insertData
|
||||
async function insertData(wsSql) {
|
||||
let wsSql = null;
|
||||
try {
|
||||
wsSql = await createConnect();
|
||||
let insertQuery = "INSERT INTO " +
|
||||
"power.d1001 USING power.meters (location, groupId) TAGS('California.SanFrancisco', 2) " +
|
||||
"VALUES " +
|
||||
"(NOW + 1a, 10.30000, 219, 0.31000) " +
|
||||
"(NOW + 2a, 12.60000, 218, 0.33000) " +
|
||||
"(NOW + 3a, 12.30000, 221, 0.31000) " +
|
||||
"power.d1002 USING power.meters TAGS('California.SanFrancisco', 3) " +
|
||||
"VALUES " +
|
||||
"(NOW + 1a, 10.30000, 218, 0.25000) ";
|
||||
taosResult = await wsSql.exec(insertQuery);
|
||||
console.log(taosResult);
|
||||
} catch (err) {
|
||||
console.error(err.code, err.message);
|
||||
} finally {
|
||||
if (wsSql) {
|
||||
await wsSql.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
// ANCHOR_END: insertData
|
||||
|
||||
// ANCHOR: queryData
|
||||
async function queryData() {
|
||||
let wsRows = null;
|
||||
let wsSql = null;
|
||||
try {
|
||||
wsSql = await createConnect();
|
||||
wsRows = await wsSql.query('select * from meters');
|
||||
let meta = wsRows.getMeta();
|
||||
console.log("wsRow:meta:=>", meta);
|
||||
while (await wsRows.next()) {
|
||||
let result = wsRows.getData();
|
||||
console.log('queryRes.Scan().then=>', result);
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
console.error(err.code, err.message);
|
||||
}
|
||||
finally {
|
||||
if (wsRows) {
|
||||
await wsRows.close();
|
||||
}
|
||||
if (wsSql) {
|
||||
await wsSql.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
// ANCHOR_END: queryData
|
||||
|
||||
// ANCHOR: sqlWithReqid
|
||||
async function sqlWithReqid(wsSql) {
|
||||
let insertQuery = "INSERT INTO " +
|
||||
"power.d1001 USING power.meters (location, groupId) TAGS('California.SanFrancisco', 2) " +
|
||||
"VALUES " +
|
||||
"(NOW + 1a, 10.30000, 219, 0.31000) " +
|
||||
"(NOW + 2a, 12.60000, 218, 0.33000) " +
|
||||
"(NOW + 3a, 12.30000, 221, 0.31000) " +
|
||||
"power.d1002 USING power.meters TAGS('California.SanFrancisco', 3) " +
|
||||
"VALUES " +
|
||||
"(NOW + 1a, 10.30000, 218, 0.25000) ";
|
||||
|
||||
let wsRows = null;
|
||||
let wsSql = null;
|
||||
try {
|
||||
wsSql = await createConnect();
|
||||
taosResult = await wsSql.exec(insertQuery, 1);
|
||||
wsRows = await wsSql.query('select * from meters', 2);
|
||||
let meta = wsRows.getMeta();
|
||||
console.log("wsRow:meta:=>", meta);
|
||||
while (await wsRows.next()) {
|
||||
let result = wsRows.getData();
|
||||
console.log('queryRes.Scan().then=>', result);
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
console.error(err.code, err.message);
|
||||
}
|
||||
finally {
|
||||
if (wsRows) {
|
||||
await wsRows.close();
|
||||
}
|
||||
if (wsSql) {
|
||||
await wsSql.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
// ANCHOR_END: sqlWithReqid
|
||||
|
||||
async function test() {
|
||||
await createDbAndTable();
|
||||
await insertData();
|
||||
await queryData();
|
||||
await sqlWithReqid();
|
||||
taos.destroy();
|
||||
}
|
||||
|
||||
test()
|
|
@ -0,0 +1,60 @@
|
|||
const taos = require("@tdengine/websocket");
|
||||
|
||||
let db = 'power';
|
||||
let stable = 'meters';
|
||||
let tags = ['California.SanFrancisco', 3];
|
||||
let values = [
|
||||
[1706786044994, 1706786044995, 1706786044996],
|
||||
[10.2, 10.3, 10.4],
|
||||
[292, 293, 294],
|
||||
[0.32, 0.33, 0.34],
|
||||
];
|
||||
|
||||
async function prepare() {
|
||||
let dsn = 'ws://localhost:6041'
|
||||
let conf = new taos.WSConfig(dsn);
|
||||
conf.setUser('root')
|
||||
conf.setPwd('taosdata')
|
||||
conf.setDb(db)
|
||||
let wsSql = await taos.sqlConnect(conf);
|
||||
await wsSql.exec(`CREATE DATABASE IF NOT EXISTS ${db} KEEP 3650 DURATION 10 BUFFER 16 WAL_LEVEL 1;`);
|
||||
await wsSql.exec(`CREATE STABLE IF NOT EXISTS ${db}.${stable} (ts timestamp, current float, voltage int, phase float) TAGS (location binary(64), groupId int);`);
|
||||
return wsSql
|
||||
}
|
||||
|
||||
(async () => {
|
||||
let stmt = null;
|
||||
let connector = null;
|
||||
try {
|
||||
connector = await prepare();
|
||||
stmt = await connector.stmtInit();
|
||||
await stmt.prepare(`INSERT INTO ? USING ${db}.${stable} (location, groupId) TAGS (?, ?) VALUES (?, ?, ?, ?)`);
|
||||
await stmt.setTableName('d1001');
|
||||
let tagParams = stmt.newStmtParam();
|
||||
tagParams.setVarchar([tags[0]]);
|
||||
tagParams.setInt([tags[1]]);
|
||||
await stmt.setTags(tagParams);
|
||||
|
||||
let bindParams = stmt.newStmtParam();
|
||||
bindParams.setTimestamp(values[0]);
|
||||
bindParams.setFloat(values[1]);
|
||||
bindParams.setInt(values[2]);
|
||||
bindParams.setFloat(values[3]);
|
||||
await stmt.bind(bindParams);
|
||||
await stmt.batch();
|
||||
await stmt.exec();
|
||||
console.log(stmt.getLastAffected());
|
||||
}
|
||||
catch (err) {
|
||||
console.error(err.code, err.message);
|
||||
}
|
||||
finally {
|
||||
if (stmt) {
|
||||
await stmt.close();
|
||||
}
|
||||
if (connector) {
|
||||
await connector.close();
|
||||
}
|
||||
taos.destroy();
|
||||
}
|
||||
})();
|
|
@ -0,0 +1,58 @@
|
|||
const taos = require("@tdengine/websocket");
|
||||
|
||||
var host = null;
|
||||
for(var i = 2; i < global.process.argv.length; i++){
|
||||
var key = global.process.argv[i].split("=")[0];
|
||||
var value = global.process.argv[i].split("=")[1];
|
||||
if("host" == key){
|
||||
host = value;
|
||||
}
|
||||
}
|
||||
|
||||
if(host == null){
|
||||
console.log("Usage: node nodejsChecker.js host=<hostname> port=<port>");
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
let dbData = ["meters.current 1648432611249 10.3 location=California.SanFrancisco groupid=2",
|
||||
"meters.current 1648432611250 12.6 location=California.SanFrancisco groupid=2",
|
||||
"meters.current 1648432611249 10.8 location=California.LosAngeles groupid=3",
|
||||
"meters.current 1648432611250 11.3 location=California.LosAngeles groupid=3",
|
||||
"meters.voltage 1648432611249 219 location=California.SanFrancisco groupid=2",
|
||||
"meters.voltage 1648432611250 218 location=California.SanFrancisco groupid=2",
|
||||
"meters.voltage 1648432611249 221 location=California.LosAngeles groupid=3",
|
||||
"meters.voltage 1648432611250 217 location=California.LosAngeles groupid=3",];
|
||||
|
||||
async function createConnect() {
|
||||
let dsn = 'ws://' + host + ':6041'
|
||||
let conf = new taos.WSConfig(dsn);
|
||||
conf.setUser('root');
|
||||
conf.setPwd('taosdata');
|
||||
|
||||
return await taos.sqlConnect(conf);
|
||||
}
|
||||
|
||||
async function test() {
|
||||
let wsSql = null;
|
||||
let wsRows = null;
|
||||
let reqId = 0;
|
||||
try {
|
||||
wsSql = await createConnect()
|
||||
await wsSql.exec('create database if not exists power KEEP 3650 DURATION 10 BUFFER 16 WAL_LEVEL 1;', reqId++);
|
||||
await wsSql.exec('use power', reqId++);
|
||||
await wsSql.schemalessInsert(dbData, taos.SchemalessProto.OpenTSDBTelnetLineProtocol, taos.Precision.MILLI_SECONDS, 0);
|
||||
}
|
||||
catch (err) {
|
||||
console.error(err.code, err.message);
|
||||
}
|
||||
finally {
|
||||
if (wsRows) {
|
||||
await wsRows.close();
|
||||
}
|
||||
if (wsSql) {
|
||||
await wsSql.close();
|
||||
}
|
||||
taos.destroy();
|
||||
}
|
||||
}
|
||||
test()
|
|
@ -0,0 +1,90 @@
|
|||
const taos = require("@tdengine/websocket");
|
||||
|
||||
const db = 'power';
|
||||
const stable = 'meters';
|
||||
const topics = ['power_meters_topic'];
|
||||
|
||||
// ANCHOR: create_consumer
|
||||
async function createConsumer() {
|
||||
let configMap = new Map([
|
||||
[taos.TMQConstants.GROUP_ID, "gId"],
|
||||
[taos.TMQConstants.CONNECT_USER, "root"],
|
||||
[taos.TMQConstants.CONNECT_PASS, "taosdata"],
|
||||
[taos.TMQConstants.AUTO_OFFSET_RESET, "latest"],
|
||||
[taos.TMQConstants.CLIENT_ID, 'test_tmq_client'],
|
||||
[taos.TMQConstants.WS_URL, 'ws://localhost:6041'],
|
||||
[taos.TMQConstants.ENABLE_AUTO_COMMIT, 'true'],
|
||||
[taos.TMQConstants.AUTO_COMMIT_INTERVAL_MS, '1000']
|
||||
]);
|
||||
return await taos.tmqConnect(configMap);
|
||||
}
|
||||
// ANCHOR_END: create_consumer
|
||||
|
||||
async function prepare() {
|
||||
let conf = new taos.WSConfig('ws://localhost:6041');
|
||||
conf.setUser('root')
|
||||
conf.setPwd('taosdata')
|
||||
conf.setDb('power')
|
||||
const createDB = `CREATE DATABASE IF NOT EXISTS POWER ${db} KEEP 3650 DURATION 10 BUFFER 16 WAL_LEVEL 1;`;
|
||||
const createStable = `CREATE STABLE IF NOT EXISTS ${db}.${stable} (ts timestamp, current float, voltage int, phase float) TAGS (location binary(64), groupId int);`;
|
||||
|
||||
let wsSql = await taos.sqlConnect(conf);
|
||||
await wsSql.exec(createDB);
|
||||
await wsSql.exec(createStable);
|
||||
|
||||
// ANCHOR: create_topic
|
||||
let createTopic = `CREATE TOPIC IF NOT EXISTS ${topics[0]} AS SELECT * FROM ${db}.${stable}`;
|
||||
await wsSql.exec(createTopic);
|
||||
// ANCHOR_END: create_topic
|
||||
|
||||
for (let i = 0; i < 10; i++) {
|
||||
await wsSql.exec(`INSERT INTO d1001 USING ${stable} (location, groupId) TAGS ("California.SanFrancisco", 3) VALUES (NOW, ${10 + i}, ${200 + i}, ${0.32 + i})`);
|
||||
}
|
||||
wsSql.Close();
|
||||
}
|
||||
|
||||
// ANCHOR: subscribe
|
||||
async function subscribe(consumer) {
|
||||
await consumer.subscribe(topics);
|
||||
for (let i = 0; i < 5; i++) {
|
||||
let res = await consumer.poll(500);
|
||||
for (let [key, value] of res) {
|
||||
console.log(key, value);
|
||||
}
|
||||
if (res.size == 0) {
|
||||
break;
|
||||
}
|
||||
await consumer.commit();
|
||||
}
|
||||
}
|
||||
// ANCHOR_END: subscribe
|
||||
|
||||
async function test() {
|
||||
let consumer = null;
|
||||
try {
|
||||
await prepare();
|
||||
let consumer = await createConsumer()
|
||||
await subscribe(consumer)
|
||||
// ANCHOR: assignment
|
||||
let assignment = await consumer.assignment();
|
||||
console.log(assignment);
|
||||
|
||||
assignment = await consumer.seekToBeginning(assignment);
|
||||
for(let i in assignment) {
|
||||
console.log("seek after:", assignment[i])
|
||||
}
|
||||
// ANCHOR_END: assignment
|
||||
await consumer.unsubscribe();
|
||||
}
|
||||
catch (err) {
|
||||
console.error(err.code, err.message);
|
||||
}
|
||||
finally {
|
||||
if (consumer) {
|
||||
await consumer.close();
|
||||
}
|
||||
taos.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
test()
|
|
@ -1,12 +1,14 @@
|
|||
import taos
|
||||
|
||||
conn: taos.TaosConnection = taos.connect(host="localhost",
|
||||
user="root",
|
||||
password="taosdata",
|
||||
database="test",
|
||||
port=6030,
|
||||
config="/etc/taos", # for windows the default value is C:\TDengine\cfg
|
||||
timezone="Asia/Shanghai") # default your host's timezone
|
||||
conn = taos.connect(
|
||||
host="localhost",
|
||||
user="root",
|
||||
password="taosdata",
|
||||
database="test",
|
||||
port=6030,
|
||||
config="/etc/taos", # for windows the default value is C:\TDengine\cfg
|
||||
timezone="Asia/Shanghai",
|
||||
) # default your host's timezone
|
||||
|
||||
server_version = conn.server_info
|
||||
print("server_version", server_version)
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
import taos
|
||||
|
||||
conn = taos.connect(
|
||||
host="localhost",
|
||||
user="root",
|
||||
password="taosdata",
|
||||
port=6030,
|
||||
)
|
||||
|
||||
db = "power"
|
||||
|
||||
conn.execute(f"DROP DATABASE IF EXISTS {db}")
|
||||
conn.execute(f"CREATE DATABASE {db}")
|
||||
|
||||
# change database. same as execute "USE db"
|
||||
conn.select_db(db)
|
||||
|
||||
# create super table
|
||||
conn.execute(
|
||||
"CREATE TABLE `meters` (`ts` TIMESTAMP, `current` FLOAT, `voltage` INT, `phase` FLOAT) TAGS (`groupid` INT, `location` BINARY(16))"
|
||||
)
|
||||
|
||||
# create table
|
||||
conn.execute("CREATE TABLE `d0` USING `meters` TAGS(0, 'Los Angles')")
|
||||
|
||||
conn.close()
|
|
@ -0,0 +1,18 @@
|
|||
import taosrest
|
||||
|
||||
conn = taosrest.connect(url="http://localhost:6041")
|
||||
|
||||
db = "power"
|
||||
|
||||
conn.execute(f"DROP DATABASE IF EXISTS {db}")
|
||||
conn.execute(f"CREATE DATABASE {db}")
|
||||
|
||||
# create super table
|
||||
conn.execute(
|
||||
f"CREATE TABLE `{db}`.`meters` (`ts` TIMESTAMP, `current` FLOAT, `voltage` INT, `phase` FLOAT) TAGS (`groupid` INT, `location` BINARY(16))"
|
||||
)
|
||||
|
||||
# create table
|
||||
conn.execute(f"CREATE TABLE `{db}`.`d0` USING `{db}`.`meters` TAGS(0, 'Los Angles')")
|
||||
|
||||
conn.close()
|
|
@ -0,0 +1,22 @@
|
|||
import taosws
|
||||
|
||||
dsn = "taosws://root:taosdata@localhost:6041"
|
||||
conn = taosws.connect(dsn)
|
||||
|
||||
db = "power"
|
||||
|
||||
conn.execute(f"DROP DATABASE IF EXISTS {db}")
|
||||
conn.execute(f"CREATE DATABASE {db}")
|
||||
|
||||
# change database.
|
||||
conn.execute(f"USE {db}")
|
||||
|
||||
# create super table
|
||||
conn.execute(
|
||||
"CREATE TABLE `meters` (`ts` TIMESTAMP, `current` FLOAT, `voltage` INT, `phase` FLOAT) TAGS (`groupid` INT, `location` BINARY(16))"
|
||||
)
|
||||
|
||||
# create table
|
||||
conn.execute("CREATE TABLE `d0` USING `meters` TAGS(0, 'Los Angles')")
|
||||
|
||||
conn.close()
|
|
@ -0,0 +1,76 @@
|
|||
import taos
|
||||
|
||||
conn = taos.connect(
|
||||
host="localhost",
|
||||
user="root",
|
||||
password="taosdata",
|
||||
port=6030,
|
||||
)
|
||||
|
||||
db = "power"
|
||||
|
||||
conn.execute(f"DROP DATABASE IF EXISTS {db}")
|
||||
conn.execute(f"CREATE DATABASE {db}")
|
||||
|
||||
# change database. same as execute "USE db"
|
||||
conn.select_db(db)
|
||||
|
||||
# create super table
|
||||
conn.execute(
|
||||
"CREATE STABLE power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (location BINARY(64), groupId INT)"
|
||||
)
|
||||
|
||||
# ANCHOR: insert
|
||||
# insert data
|
||||
sql = """
|
||||
INSERT INTO
|
||||
power.d1001 USING power.meters TAGS('California.SanFrancisco', 2)
|
||||
VALUES ('2018-10-03 14:38:05.000', 10.30000, 219, 0.31000)
|
||||
('2018-10-03 14:38:15.000', 12.60000, 218, 0.33000) ('2018-10-03 14:38:16.800', 12.30000, 221, 0.31000)
|
||||
power.d1002 USING power.meters TAGS('California.SanFrancisco', 3)
|
||||
VALUES ('2018-10-03 14:38:16.650', 10.30000, 218, 0.25000)
|
||||
power.d1003 USING power.meters TAGS('California.LosAngeles', 2)
|
||||
VALUES ('2018-10-03 14:38:05.500', 11.80000, 221, 0.28000) ('2018-10-03 14:38:16.600', 13.40000, 223, 0.29000)
|
||||
power.d1004 USING power.meters TAGS('California.LosAngeles', 3)
|
||||
VALUES ('2018-10-03 14:38:05.000', 10.80000, 223, 0.29000) ('2018-10-03 14:38:06.500', 11.50000, 221, 0.35000)
|
||||
"""
|
||||
|
||||
inserted = conn.execute(sql)
|
||||
assert inserted == 8
|
||||
# ANCHOR_END: insert
|
||||
|
||||
# ANCHOR: query
|
||||
# Execute a sql and get its result set. It's useful for SELECT statement
|
||||
result = conn.query("SELECT * from meters")
|
||||
|
||||
# Get fields from result
|
||||
fields = result.fields
|
||||
for field in fields:
|
||||
print(field)
|
||||
|
||||
"""
|
||||
output:
|
||||
{name: ts, type: 9, bytes: 8}
|
||||
{name: current, type: 6, bytes: 4}
|
||||
{name: voltage, type: 4, bytes: 4}
|
||||
{name: phase, type: 6, bytes: 4}
|
||||
{name: location, type: 8, bytes: 64}
|
||||
{name: groupid, type: 4, bytes: 4}
|
||||
"""
|
||||
|
||||
# Get data from result as list of tuple
|
||||
data = result.fetch_all()
|
||||
for row in data:
|
||||
print(row)
|
||||
|
||||
"""
|
||||
output:
|
||||
(datetime.datetime(2018, 10, 3, 14, 38, 16, 650000), 10.300000190734863, 218, 0.25, 'California.SanFrancisco', 3)
|
||||
...
|
||||
"""
|
||||
# ANCHOR_END: query
|
||||
|
||||
# ANCHOR: req_id
|
||||
result = conn.query("SELECT * from meters", req_id=1)
|
||||
# ANCHOR_END: req_id
|
||||
conn.close()
|
|
@ -0,0 +1,48 @@
|
|||
import taosrest
|
||||
|
||||
conn = taosrest.connect(url="http://localhost:6041")
|
||||
|
||||
db = "power"
|
||||
|
||||
conn.execute(f"DROP DATABASE IF EXISTS {db}")
|
||||
conn.execute(f"CREATE DATABASE {db}")
|
||||
|
||||
# create super table
|
||||
conn.execute(
|
||||
"CREATE STABLE power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (location BINARY(64), groupId INT)"
|
||||
)
|
||||
|
||||
# ANCHOR: insert
|
||||
# rest insert data
|
||||
sql = """
|
||||
INSERT INTO
|
||||
power.d1001 USING power.meters TAGS('California.SanFrancisco', 2)
|
||||
VALUES ('2018-10-03 14:38:05.000', 10.30000, 219, 0.31000)
|
||||
('2018-10-03 14:38:15.000', 12.60000, 218, 0.33000) ('2018-10-03 14:38:16.800', 12.30000, 221, 0.31000)
|
||||
power.d1002 USING power.meters TAGS('California.SanFrancisco', 3)
|
||||
VALUES ('2018-10-03 14:38:16.650', 10.30000, 218, 0.25000)
|
||||
power.d1003 USING power.meters TAGS('California.LosAngeles', 2)
|
||||
VALUES ('2018-10-03 14:38:05.500', 11.80000, 221, 0.28000) ('2018-10-03 14:38:16.600', 13.40000, 223, 0.29000)
|
||||
power.d1004 USING power.meters TAGS('California.LosAngeles', 3)
|
||||
VALUES ('2018-10-03 14:38:05.000', 10.80000, 223, 0.29000) ('2018-10-03 14:38:06.500', 11.50000, 221, 0.35000)
|
||||
"""
|
||||
|
||||
inserted = conn.execute(sql)
|
||||
assert inserted == 8
|
||||
# ANCHOR_END: insert
|
||||
|
||||
# ANCHOR: query
|
||||
client = taosrest.RestClient("http://localhost:6041")
|
||||
result = client.sql(f"SELECT * from {db}.meters")
|
||||
print(result)
|
||||
|
||||
"""
|
||||
output:
|
||||
{'code': 0, 'column_meta': [['ts', 'TIMESTAMP', 8], ['current', 'FLOAT', 4], ['voltage', 'INT', 4], ['phase', 'FLOAT', 4], ['location', 'VARCHAR', 64], ['groupid', 'INT', 4]], 'data': [[datetime.datetime(2018, 10, 3, 14, 38, 5), 10.3, 219, 0.31, 'California.SanFrancisco', 2], [datetime.datetime(2018, 10, 3, 14, 38, 15), 12.6, 218, 0.33, 'California.SanFrancisco', 2], [datetime.datetime(2018, 10, 3, 14, 38, 16, 800000), 12.3, 221, 0.31, 'California.SanFrancisco', 2], [datetime.datetime(2018, 10, 3, 14, 38, 16, 650000), 10.3, 218, 0.25, 'California.SanFrancisco', 3], [datetime.datetime(2018, 10, 3, 14, 38, 5, 500000), 11.8, 221, 0.28, 'California.LosAngeles', 2], [datetime.datetime(2018, 10, 3, 14, 38, 16, 600000), 13.4, 223, 0.29, 'California.LosAngeles', 2], [datetime.datetime(2018, 10, 3, 14, 38, 5), 10.8, 223, 0.29, 'California.LosAngeles', 3], [datetime.datetime(2018, 10, 3, 14, 38, 6, 500000), 11.5, 221, 0.35, 'California.LosAngeles', 3]], 'rows': 8}
|
||||
"""
|
||||
# ANCHOR_END: query
|
||||
|
||||
# ANCHOR: req_id
|
||||
result = client.sql(f"SELECT * from {db}.meters", req_id=1)
|
||||
# ANCHOR_END: req_id
|
||||
conn.close()
|
|
@ -0,0 +1,71 @@
|
|||
import taosws
|
||||
|
||||
dsn = "taosws://root:taosdata@localhost:6041"
|
||||
conn = taosws.connect(dsn)
|
||||
|
||||
db = "power"
|
||||
|
||||
conn.execute(f"DROP DATABASE IF EXISTS {db}")
|
||||
conn.execute(f"CREATE DATABASE {db}")
|
||||
|
||||
# change database.
|
||||
conn.execute(f"USE {db}")
|
||||
|
||||
# create super table
|
||||
conn.execute(
|
||||
"CREATE STABLE power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (location BINARY(64), groupId INT)"
|
||||
)
|
||||
|
||||
# ANCHOR: insert
|
||||
# ws insert data
|
||||
sql = """
|
||||
INSERT INTO
|
||||
power.d1001 USING power.meters TAGS('California.SanFrancisco', 2)
|
||||
VALUES ('2018-10-03 14:38:05.000', 10.30000, 219, 0.31000)
|
||||
('2018-10-03 14:38:15.000', 12.60000, 218, 0.33000) ('2018-10-03 14:38:16.800', 12.30000, 221, 0.31000)
|
||||
power.d1002 USING power.meters TAGS('California.SanFrancisco', 3)
|
||||
VALUES ('2018-10-03 14:38:16.650', 10.30000, 218, 0.25000)
|
||||
power.d1003 USING power.meters TAGS('California.LosAngeles', 2)
|
||||
VALUES ('2018-10-03 14:38:05.500', 11.80000, 221, 0.28000) ('2018-10-03 14:38:16.600', 13.40000, 223, 0.29000)
|
||||
power.d1004 USING power.meters TAGS('California.LosAngeles', 3)
|
||||
VALUES ('2018-10-03 14:38:05.000', 10.80000, 223, 0.29000) ('2018-10-03 14:38:06.500', 11.50000, 221, 0.35000)
|
||||
"""
|
||||
|
||||
inserted = conn.execute(sql)
|
||||
assert inserted == 8
|
||||
# ANCHOR_END: insert
|
||||
|
||||
# ANCHOR: query
|
||||
# Execute a sql and get its result set. It's useful for SELECT statement
|
||||
result = conn.query("SELECT * from meters")
|
||||
|
||||
# Get fields from result
|
||||
fields = result.fields
|
||||
for field in fields:
|
||||
print(field)
|
||||
|
||||
"""
|
||||
output:
|
||||
{name: ts, type: TIMESTAMP, bytes: 8}
|
||||
{name: current, type: FLOAT, bytes: 4}
|
||||
{name: voltage, type: INT, bytes: 4}
|
||||
{name: phase, type: FLOAT, bytes: 4}
|
||||
{name: location, type: BINARY, bytes: 64}
|
||||
{name: groupid, type: INT, bytes: 4}
|
||||
"""
|
||||
|
||||
# Get rows from result
|
||||
for row in result:
|
||||
print(row)
|
||||
|
||||
"""
|
||||
output:
|
||||
('2018-10-03 14:38:05 +08:00', 10.300000190734863, 219, 0.3100000023841858, 'California.SanFrancisco', 2)
|
||||
...
|
||||
"""
|
||||
# ANCHOR_END: query
|
||||
|
||||
# ANCHOR: req_id
|
||||
result = conn.query_with_req_id("SELECT * from meters", req_id=1)
|
||||
# ANCHOR_END: req_id
|
||||
conn.close()
|
|
@ -0,0 +1,36 @@
|
|||
import taos
|
||||
|
||||
conn = taos.connect(
|
||||
host="localhost",
|
||||
user="root",
|
||||
password="taosdata",
|
||||
port=6030,
|
||||
)
|
||||
|
||||
db = "power"
|
||||
|
||||
conn.execute(f"DROP DATABASE IF EXISTS {db}")
|
||||
conn.execute(f"CREATE DATABASE {db}")
|
||||
|
||||
# change database. same as execute "USE db"
|
||||
conn.select_db(db)
|
||||
|
||||
lineDemo = [
|
||||
"meters,groupid=2,location=California.SanFrancisco current=10.3000002f64,voltage=219i32,phase=0.31f64 1626006833639000000"
|
||||
]
|
||||
telnetDemo = ["stb0_0 1707095283260 4 host=host0 interface=eth0"]
|
||||
jsonDemo = [
|
||||
'{"metric": "meter_current","timestamp": 1626846400,"value": 10.3, "tags": {"groupid": 2, "location": "California.SanFrancisco", "id": "d1001"}}'
|
||||
]
|
||||
|
||||
conn.schemaless_insert(
|
||||
lineDemo, taos.SmlProtocol.LINE_PROTOCOL, taos.SmlPrecision.MILLI_SECONDS
|
||||
)
|
||||
conn.schemaless_insert(
|
||||
telnetDemo, taos.SmlProtocol.TELNET_PROTOCOL, taos.SmlPrecision.MICRO_SECONDS
|
||||
)
|
||||
conn.schemaless_insert(
|
||||
jsonDemo, taos.SmlProtocol.JSON_PROTOCOL, taos.SmlPrecision.MILLI_SECONDS
|
||||
)
|
||||
|
||||
conn.close()
|
|
@ -0,0 +1,46 @@
|
|||
import taosws
|
||||
|
||||
dsn = "taosws://root:taosdata@localhost:6041"
|
||||
conn = taosws.connect(dsn)
|
||||
|
||||
db = "power"
|
||||
|
||||
conn.execute(f"DROP DATABASE IF EXISTS {db}")
|
||||
conn.execute(f"CREATE DATABASE {db}")
|
||||
|
||||
# change database.
|
||||
conn = taosws.connect(f"{dsn}/{db}")
|
||||
|
||||
lineDemo = [
|
||||
"meters,groupid=2,location=California.SanFrancisco current=10.3000002f64,voltage=219i32,phase=0.31f64 1626006833639000000"
|
||||
]
|
||||
telnetDemo = ["stb0_0 1707095283260 4 host=host0 interface=eth0"]
|
||||
jsonDemo = [
|
||||
'{"metric": "meter_current","timestamp": 1626846400,"value": 10.3, "tags": {"groupid": 2, "location": "California.SanFrancisco", "id": "d1001"}}'
|
||||
]
|
||||
|
||||
conn.schemaless_insert(
|
||||
lines=lineDemo,
|
||||
protocol=taosws.PySchemalessProtocol.Line,
|
||||
precision=taosws.PySchemalessPrecision.Millisecond,
|
||||
ttl=1,
|
||||
req_id=1,
|
||||
)
|
||||
|
||||
conn.schemaless_insert(
|
||||
lines=telnetDemo,
|
||||
protocol=taosws.PySchemalessProtocol.Telnet,
|
||||
precision=taosws.PySchemalessPrecision.Microsecond,
|
||||
ttl=1,
|
||||
req_id=2,
|
||||
)
|
||||
|
||||
conn.schemaless_insert(
|
||||
lines=jsonDemo,
|
||||
protocol=taosws.PySchemalessProtocol.Json,
|
||||
precision=taosws.PySchemalessPrecision.Millisecond,
|
||||
ttl=1,
|
||||
req_id=3,
|
||||
)
|
||||
|
||||
conn.close()
|
|
@ -0,0 +1,53 @@
|
|||
import taos
|
||||
|
||||
conn = taos.connect(
|
||||
host="localhost",
|
||||
user="root",
|
||||
password="taosdata",
|
||||
port=6030,
|
||||
)
|
||||
|
||||
db = "power"
|
||||
|
||||
conn.execute(f"DROP DATABASE IF EXISTS {db}")
|
||||
conn.execute(f"CREATE DATABASE {db}")
|
||||
|
||||
# change database. same as execute "USE db"
|
||||
conn.select_db(db)
|
||||
|
||||
# create super table
|
||||
conn.execute(
|
||||
"CREATE STABLE power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (location BINARY(64), groupId INT)"
|
||||
)
|
||||
|
||||
# ANCHOR: stmt
|
||||
sql = "INSERT INTO ? USING meters TAGS(?,?) VALUES (?,?,?,?)"
|
||||
stmt = conn.statement(sql)
|
||||
|
||||
tbname = "power.d1001"
|
||||
|
||||
tags = taos.new_bind_params(2)
|
||||
tags[0].binary(["California.SanFrancisco"])
|
||||
tags[1].int([2])
|
||||
|
||||
stmt.set_tbname_tags(tbname, tags)
|
||||
|
||||
params = taos.new_bind_params(4)
|
||||
params[0].timestamp((1626861392589, 1626861392591, 1626861392592))
|
||||
params[1].float((10.3, 12.6, 12.3))
|
||||
params[2].int([194, 200, 201])
|
||||
params[3].float([0.31, 0.33, 0.31])
|
||||
|
||||
stmt.bind_param_batch(params)
|
||||
|
||||
stmt.execute()
|
||||
|
||||
stmt.close()
|
||||
# ANCHOR_END: stmt
|
||||
|
||||
result = conn.query("SELECT * from meters")
|
||||
|
||||
for row in result.fetch_all():
|
||||
print(row)
|
||||
|
||||
conn.close()
|
|
@ -0,0 +1,52 @@
|
|||
import taosws
|
||||
|
||||
dsn = "taosws://root:taosdata@localhost:6041"
|
||||
conn = taosws.connect(dsn)
|
||||
|
||||
db = "power"
|
||||
|
||||
conn.execute(f"DROP DATABASE IF EXISTS {db}")
|
||||
conn.execute(f"CREATE DATABASE {db}")
|
||||
|
||||
# change database.
|
||||
conn.execute(f"USE {db}")
|
||||
|
||||
# create super table
|
||||
conn.execute(
|
||||
"CREATE STABLE power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (location BINARY(64), groupId INT)"
|
||||
)
|
||||
|
||||
# ANCHOR: stmt
|
||||
sql = "INSERT INTO ? USING meters TAGS(?,?) VALUES (?,?,?,?)"
|
||||
stmt = conn.statement()
|
||||
stmt.prepare(sql)
|
||||
|
||||
tbname = "power.d1001"
|
||||
|
||||
tags = [
|
||||
taosws.varchar_to_tag("California.SanFrancisco"),
|
||||
taosws.int_to_tag(2),
|
||||
]
|
||||
|
||||
stmt.set_tbname_tags(tbname, tags)
|
||||
|
||||
stmt.bind_param(
|
||||
[
|
||||
taosws.millis_timestamps_to_column(
|
||||
[1626861392589, 1626861392591, 1626861392592]
|
||||
),
|
||||
taosws.floats_to_column([10.3, 12.6, 12.3]),
|
||||
taosws.ints_to_column([194, 200, 201]),
|
||||
taosws.floats_to_column([0.31, 0.33, 0.31]),
|
||||
]
|
||||
)
|
||||
|
||||
stmt.add_batch()
|
||||
rows = stmt.execute()
|
||||
|
||||
assert rows == 3
|
||||
|
||||
stmt.close()
|
||||
# ANCHOR_END: stmt
|
||||
|
||||
conn.close()
|
|
@ -0,0 +1,84 @@
|
|||
import taos
|
||||
|
||||
conn = taos.connect(
|
||||
host="localhost",
|
||||
user="root",
|
||||
password="taosdata",
|
||||
port=6030,
|
||||
)
|
||||
|
||||
db = "power"
|
||||
topic = "topic_meters"
|
||||
|
||||
conn.execute(f"DROP TOPIC IF EXISTS {topic}")
|
||||
conn.execute(f"DROP DATABASE IF EXISTS {db}")
|
||||
conn.execute(f"CREATE DATABASE {db}")
|
||||
|
||||
# change database. same as execute "USE db"
|
||||
conn.select_db(db)
|
||||
|
||||
# create super table
|
||||
conn.execute(
|
||||
"CREATE STABLE power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (location BINARY(64), groupId INT)"
|
||||
)
|
||||
|
||||
# ANCHOR: create_topic
|
||||
# create topic
|
||||
conn.execute(
|
||||
f"CREATE TOPIC IF NOT EXISTS {topic} AS SELECT ts, current, voltage, phase, groupid, location FROM meters"
|
||||
)
|
||||
# ANCHOR_END: create_topic
|
||||
|
||||
# ANCHOR: create_consumer
|
||||
from taos.tmq import Consumer
|
||||
|
||||
consumer = Consumer(
|
||||
{
|
||||
"group.id": "1",
|
||||
"td.connect.user": "root",
|
||||
"td.connect.pass": "taosdata",
|
||||
"enable.auto.commit": "true",
|
||||
}
|
||||
)
|
||||
# ANCHOR_END: create_consumer
|
||||
|
||||
# ANCHOR: subscribe
|
||||
consumer.subscribe([topic])
|
||||
# ANCHOR_END: subscribe
|
||||
|
||||
try:
|
||||
# ANCHOR: consume
|
||||
while True:
|
||||
res = consumer.poll(1)
|
||||
if not res:
|
||||
break
|
||||
err = res.error()
|
||||
if err is not None:
|
||||
raise err
|
||||
val = res.value()
|
||||
|
||||
for block in val:
|
||||
print(block.fetchall())
|
||||
# ANCHOR_END: consume
|
||||
|
||||
# ANCHOR: assignment
|
||||
assignments = consumer.assignment()
|
||||
for assignment in assignments:
|
||||
print(assignment)
|
||||
# ANCHOR_END: assignment
|
||||
|
||||
# ANCHOR: seek
|
||||
offset = taos.tmq.TopicPartition(
|
||||
topic=topic,
|
||||
partition=assignment.partition,
|
||||
offset=0,
|
||||
)
|
||||
consumer.seek(offset)
|
||||
# ANCHOR_END: seek
|
||||
finally:
|
||||
# ANCHOR: unsubscribe
|
||||
consumer.unsubscribe()
|
||||
consumer.close()
|
||||
# ANCHOR_END: unsubscribe
|
||||
|
||||
conn.close()
|
|
@ -9,5 +9,7 @@ anyhow = "1"
|
|||
chrono = "0.4"
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
tokio = { version = "1", features = ["rt", "macros", "rt-multi-thread"] }
|
||||
log = "0.4"
|
||||
pretty_env_logger = "0.5.0"
|
||||
|
||||
taos = { version = "0.4.8" }
|
||||
taos = { version = "0.11.8" }
|
|
@ -23,7 +23,7 @@ docker pull tdengine/tdengine:3.0.1.4
|
|||
然后只需执行下面的命令:
|
||||
|
||||
```shell
|
||||
docker run -d -p 6030:6030 -p 6041:6041 -p 6043-6049:6043-6049 -p 6043-6049:6043-6049/udp tdengine/tdengine
|
||||
docker run -d -p 6030:6030 -p 6041:6041 -p 6043-6060:6043-6060 -p 6043-6060:6043-6060/udp tdengine/tdengine
|
||||
```
|
||||
|
||||
注意:TDengine 3.0 服务端仅使用 6030 TCP 端口。6041 为 taosAdapter 所使用提供 REST 服务端口。6043-6049 为 taosAdapter 提供第三方应用接入所使用端口,可根据需要选择是否打开。
|
||||
|
@ -33,7 +33,7 @@ docker run -d -p 6030:6030 -p 6041:6041 -p 6043-6049:6043-6049 -p 6043-6049:6043
|
|||
```shell
|
||||
docker run -d -v ~/data/taos/dnode/data:/var/lib/taos \
|
||||
-v ~/data/taos/dnode/log:/var/log/taos \
|
||||
-p 6030:6030 -p 6041:6041 -p 6043-6049:6043-6049 -p 6043-6049:6043-6049/udp tdengine/tdengine
|
||||
-p 6030:6030 -p 6041:6041 -p 6043-6060:6043-6060 -p 6043-6060:6043-6060/udp tdengine/tdengine
|
||||
```
|
||||
|
||||
:::note
|
||||
|
@ -59,7 +59,7 @@ docker exec -it <container name> bash
|
|||
|
||||
注:Docker 工具自身的下载和使用请参考 [Docker 官网文档](https://docs.docker.com/get-docker/)。
|
||||
|
||||
## 运行 TDengine CLI
|
||||
## TDengine 命令行界面
|
||||
|
||||
进入容器,执行 `taos`:
|
||||
|
||||
|
@ -69,7 +69,13 @@ $ taos
|
|||
taos>
|
||||
```
|
||||
|
||||
## 使用 taosBenchmark 体验写入速度
|
||||
## TDengine 图形化界面
|
||||
|
||||
从 TDengine 3.3.0.0 开始,TDengine docker image 中增加了一个新的 web 组件:taos-explorer, 可以使用它进行数据库、超级表、子表、数据的查看和管理。其上也有一些只在企业版中才提供的高级特性,如需要可联系 TDengine 销售团队。
|
||||
|
||||
使用 taos-explorer,需要从浏览器访问其映射在主机上的端口,假定主机名为 abc.com,映射到主机的端口为 6060,则需从浏览器访问 http://abc.com:6060. taos-explorer 默认在容器内使用 6060 端口。初次使用需要使用企业邮箱进行注册,注册后即可使用数据库中的用户名和密码登录。
|
||||
|
||||
## 体验写入速度
|
||||
|
||||
可以使用 TDengine 的自带工具 taosBenchmark 快速体验 TDengine 的写入速度。
|
||||
|
||||
|
@ -85,7 +91,7 @@ $ taosBenchmark
|
|||
|
||||
taosBenchmark 命令本身带有很多选项,配置表的数目、记录条数等等,您可以设置不同参数进行体验,请执行 `taosBenchmark --help` 详细列出。taosBenchmark 详细使用方法请参照[如何使用 taosBenchmark 对 TDengine 进行性能测试](https://www.taosdata.com/2021/10/09/3111.html)和 [taosBenchmark 参考手册](../../reference/taosbenchmark)。
|
||||
|
||||
## 使用 TDengine CLI 体验查询速度
|
||||
## 体验查询速度
|
||||
|
||||
使用上述 `taosBenchmark` 插入数据后,可以在 TDengine CLI(taos)输入查询命令,体验查询速度。
|
||||
|
||||
|
|
|
@ -32,6 +32,10 @@ gcc 版本 - 9.3.1或以上;
|
|||
|
||||
## 安装
|
||||
|
||||
**注意**
|
||||
|
||||
从TDengine 3.0.6.0 开始,不再提供单独的 taosTools 安装包,原 taosTools 安装包中包含的工具都在 TDengine-server 安装包中,如果需要请直接下载 TDengine -server 安装包。
|
||||
|
||||
<Tabs>
|
||||
<TabItem label="Deb 安装" value="debinst">
|
||||
|
||||
|
@ -119,11 +123,17 @@ apt-get 方式只适用于 Debian 或 Ubuntu 系统。
|
|||
</TabItem>
|
||||
<TabItem label="Windows 安装" value="windows">
|
||||
|
||||
注意:目前 TDengine 在 Windows 平台上只支持 Windows Server 2016/2019 和 Windows 10/11。
|
||||
**注意**
|
||||
- 目前 TDengine 在 Windows 平台上只支持 Windows Server 2016/2019 和 Windows 10/11。
|
||||
- 从 TDengine 3.1.0.0 开始,只提供 Windows 客户端安装包。如果需要 Windows 服务端安装包,请联系 TDengine 销售团队升级为企业版。
|
||||
- Windows 上需要安装 VC 运行时库,可在此下载安装 [VC运行时库](https://learn.microsoft.com/zh-cn/cpp/windows/latest-supported-vc-redist?view=msvc-170), 如果已经安装此运行库可忽略。
|
||||
|
||||
按照以下步骤安装:
|
||||
|
||||
1. 从列表中下载获得 exe 安装程序;
|
||||
<PkgListV3 type={3}/>
|
||||
2. 运行可执行程序来安装 TDengine。
|
||||
Note: 从 3.0.1.7 开始,只提供 TDengine 客户端的 Windows 客户端的下载。想要使用TDengine 服务端的 Windows 版本,请联系销售升级为企业版本。
|
||||
|
||||
</TabItem>
|
||||
<TabItem label="macOS 安装" value="macos">
|
||||
|
@ -153,38 +163,25 @@ apt-get 方式只适用于 Debian 或 Ubuntu 系统。
|
|||
|
||||
```bash
|
||||
systemctl start taosd
|
||||
systemctl start taosadapter
|
||||
systemctl start taoskeeper
|
||||
systemctl start taos-explorer
|
||||
```
|
||||
|
||||
检查服务是否正常工作:
|
||||
你也可以直接运行 start-all.sh 脚本来启动上面的所有服务
|
||||
```bash
|
||||
start-all.sh
|
||||
```
|
||||
|
||||
可以使用 systemctl 来单独管理上面的每一个服务
|
||||
|
||||
```bash
|
||||
systemctl start taosd
|
||||
systemctl stop taosd
|
||||
systemctl restart taosd
|
||||
systemctl status taosd
|
||||
```
|
||||
|
||||
如果服务进程处于活动状态,则 status 指令会显示如下的相关信息:
|
||||
|
||||
```
|
||||
Active: active (running)
|
||||
```
|
||||
|
||||
如果后台服务进程处于停止状态,则 status 指令会显示如下的相关信息:
|
||||
|
||||
```
|
||||
Active: inactive (dead)
|
||||
```
|
||||
|
||||
如果 TDengine 服务正常工作,那么您可以通过 TDengine 的命令行程序 `taos` 来访问并体验 TDengine。
|
||||
|
||||
如下 `systemctl` 命令可以帮助你管理 TDengine 服务:
|
||||
|
||||
- 启动服务进程:`systemctl start taosd`
|
||||
|
||||
- 停止服务进程:`systemctl stop taosd`
|
||||
|
||||
- 重启服务进程:`systemctl restart taosd`
|
||||
|
||||
- 查看服务状态:`systemctl status taosd`
|
||||
|
||||
:::info
|
||||
|
||||
- `systemctl` 命令需要 _root_ 权限来运行,如果您非 _root_ 用户,请在命令前添加 `sudo`。
|
||||
|
@ -193,35 +190,39 @@ Active: inactive (dead)
|
|||
|
||||
:::
|
||||
|
||||
**TDengine 命令行(CLI)**
|
||||
|
||||
为便于检查 TDengine 的状态,执行数据库(Database)的各种即席(Ad Hoc)查询,TDengine 提供一命令行应用程序(以下简称为 TDengine CLI)taos。要进入 TDengine 命令行,您只要在终端执行 `taos` 即可。
|
||||
|
||||
</TabItem>
|
||||
|
||||
<TabItem label="Windows 系统" value="windows">
|
||||
|
||||
安装后,可以在拥有管理员权限的 cmd 窗口执行 `sc start taosd` 或在 `C:\TDengine` 目录下,运行 `taosd.exe` 来启动 TDengine 服务进程。如需使用 http/REST 服务,请执行 `sc start taosadapter` 或运行 `taosadapter.exe` 来启动 taosAdapter 服务进程。
|
||||
|
||||
**TDengine 命令行(CLI)**
|
||||
|
||||
为便于检查 TDengine 的状态,执行数据库(Database)的各种即席(Ad Hoc)查询,TDengine 提供一命令行应用程序(以下简称为 TDengine CLI)taos。要进入 TDengine 命令行,您只要在终端执行 `taos` 即可。
|
||||
|
||||
</TabItem>
|
||||
|
||||
<TabItem label="macOS 系统" value="macos">
|
||||
|
||||
安装后,在应用程序目录下,双击 TDengine 图标来启动程序,也可以运行 `sudo launchctl start com.tdengine.taosd` 来启动 TDengine 服务进程。
|
||||
安装后,在应用程序目录下,双击 TDengine 图标来启动程序,也可以运行 `sudo launchctl start ` 来启动 TDengine 服务进程。
|
||||
|
||||
如下 `launchctl` 命令用于管理 TDengine 服务:
|
||||
|
||||
- 启动服务进程:`sudo launchctl start com.tdengine.taosd`
|
||||
```bash
|
||||
sudo launchctl start com.tdengine.taosd
|
||||
sudo launchctl start com.tdengine.taosadapter
|
||||
sudo launchctl start com.tdengine.taoskeeper
|
||||
sudo launchctl start com.tdengine.taos-explorer
|
||||
```
|
||||
|
||||
- 停止服务进程:`sudo launchctl stop com.tdengine.taosd`
|
||||
你也可以直接运行 start-all.sh 脚本来启动上面的所有服务
|
||||
```bash
|
||||
start-all.sh
|
||||
```
|
||||
|
||||
- 查看服务状态:`sudo launchctl list | grep taosd`
|
||||
可以使用 `launchctl` 命令管理上面提到的每个 TDengine 服务,以下示例使用 `taosd` :
|
||||
|
||||
- 查看服务详细信息:`launchctl print system/com.tdengine.taosd`
|
||||
```bash
|
||||
sudo launchctl start com.tdengine.taosd
|
||||
sudo launchctl stop com.tdengine.taosd
|
||||
sudo launchctl list | grep taosd
|
||||
sudo launchctl print system/com.tdengine.taosd
|
||||
```
|
||||
|
||||
:::info
|
||||
|
||||
|
@ -232,18 +233,13 @@ Active: inactive (dead)
|
|||
|
||||
:::
|
||||
|
||||
**TDengine 命令行(CLI)**
|
||||
|
||||
为便于检查 TDengine 的状态,执行数据库(Database)的各种即席(Ad Hoc)查询,TDengine 提供一命令行应用程序(以下简称为 TDengine CLI)taos。要进入 TDengine 命令行,您只要在 Windows 终端的 C:\TDengine 目录下,运行 taos.exe 来启动 TDengine 命令行。
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
```bash
|
||||
taos
|
||||
```
|
||||
|
||||
如果连接服务成功,将会打印出欢迎消息和版本信息。如果失败,则会打印错误消息出来(请参考 [FAQ](/train-faq/faq) 来解决终端连接服务端失败的问题)。TDengine CLI 的提示符号如下:
|
||||
## TDengine 命令行(CLI)
|
||||
|
||||
为便于检查 TDengine 的状态,执行数据库(Database)的各种即席(Ad Hoc)查询,TDengine 提供一命令行应用程序(以下简称为 TDengine CLI)taos。要进入 TDengine 命令行,您只要在终端执行 `taos` (Linux/Mac) 或 `taos.exe` (Windows) 即可。 TDengine CLI 的提示符号如下:
|
||||
|
||||
```cmd
|
||||
taos>
|
||||
|
@ -269,6 +265,12 @@ Query OK, 2 row(s) in set (0.003128s)
|
|||
|
||||
除执行 SQL 语句外,系统管理员还可以从 TDengine CLI 进行检查系统运行状态、添加删除用户账号等操作。TDengine CLI 连同应用驱动也可以独立安装在机器上运行,更多细节请参考 [TDengine 命令行](../../reference/taos-shell/)。
|
||||
|
||||
## TDengine 图形化界面
|
||||
|
||||
从 TDengine 3.3.0.0 开始,TDengine 发布包中增加了一个新的 web 组件:taos-explorer, 可以使用它进行数据库、超级表、子表、数据的查看和管理。其上也有一些只在企业版中才提供的高级特性,如需要可联系 TDengine 销售团队。
|
||||
|
||||
使用 taos-explorer,需要从浏览器访问其映射在主机上的端口,假定主机名为 abc.com,映射到主机的端口为 6060,则需从浏览器访问 http://abc.com:6060. taos-explorer 默认在容器内使用 6060 端口。初次使用需要使用企业邮箱进行注册,注册后即可使用数据库中的用户名和密码登录
|
||||
|
||||
## 使用 taosBenchmark 体验写入速度
|
||||
|
||||
可以使用 TDengine 的自带工具 taosBenchmark 快速体验 TDengine 的写入速度。
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
```rust title="原生连接/REST 连接"
|
||||
```rust title="原生连接"
|
||||
{{#include docs/examples/rust/nativeexample/examples/connect.rs}}
|
||||
```
|
||||
|
||||
:::note
|
||||
对于 Rust 连接器, 连接方式的不同只体现在使用的特性不同。如果启用了 "rest" 特性,那么只有 RESTful 的实现会被编译进来。
|
||||
对于 Rust 连接器, 连接方式的不同只体现在使用的特性不同。如果启用了 "ws" 特性,那么只有 Websocket 的实现会被编译进来。
|
||||
|
||||
:::
|
||||
|
|
After Width: | Height: | Size: 14 KiB |
|
@ -25,17 +25,24 @@ TDengine 提供了丰富的应用程序开发接口,为了便于用户快速
|
|||
|
||||
## 连接器建立连接的方式
|
||||
|
||||
连接器建立连接的方式,TDengine 提供两种:
|
||||
连接器建立连接的方式,TDengine 提供三种:
|
||||
|
||||
1. 通过 taosAdapter 组件提供的 REST API 建立与 taosd 的连接,这种连接方式下文中简称“REST 连接”
|
||||
2. 通过客户端驱动程序 taosc 直接与服务端程序 taosd 建立连接,这种连接方式下文中简称“原生连接”。
|
||||
1. 通过客户端驱动程序 taosc 直接与服务端程序 taosd 建立连接,这种连接方式下文中简称 “原生连接”。
|
||||
2. 通过 taosAdapter 组件提供的 REST API 建立与 taosd 的连接,这种连接方式下文中简称 “REST 连接”
|
||||
3. 通过 taosAdapter 组件提供的 Websocket API 建立与 taosd 的连接,这种连接方式下文中简称 “Websocket 连接”
|
||||
|
||||

|
||||
|
||||
无论使用何种方式建立连接,连接器都提供了相同或相似的 API 操作数据库,都可以执行 SQL 语句,只是初始化连接的方式稍有不同,用户在使用上不会感到什么差别。
|
||||
|
||||
关键不同点在于:
|
||||
|
||||
1. 使用 REST 连接,用户无需安装客户端驱动程序 taosc,具有跨平台易用的优势,但性能要下降 30% 左右。
|
||||
2. 使用原生连接可以体验 TDengine 的全部功能,如[参数绑定接口](../../connector/cpp/#参数绑定-api)、[订阅](../../connector/cpp/#订阅和消费-api)等等。
|
||||
1. 使用 原生连接,需要保证客户端的驱动程序 taosc 和服务端的 TDengine 版本配套。
|
||||
2. 使用 REST 连接,用户无需安装客户端驱动程序 taosc,具有跨平台易用的优势,但是无法体验数据订阅和二进制数据类型等功能。另外与 原生连接 和 Websocket 连接相比,REST连接的性能最低。
|
||||
3. 使用 Websocket 连接,用户也无需安装客户端驱动程序 taosc。
|
||||
4. 连接云服务实例,必须使用 REST 连接 或 Websocket 连接。
|
||||
|
||||
一般我们建议使用 **Websocket 连接**。
|
||||
|
||||
## 安装客户端驱动 taosc
|
||||
|
||||
|
@ -122,18 +129,18 @@ driver-go 使用 cgo 封装了 taosc 的 API。cgo 需要使用 GCC 编译 C 的
|
|||
</TabItem>
|
||||
<TabItem label="Rust" value="rust">
|
||||
|
||||
编辑 `Cargo.toml` 添加 `libtaos` 依赖即可。
|
||||
编辑 `Cargo.toml` 添加 `taos` 依赖即可。
|
||||
|
||||
```toml title=Cargo.toml
|
||||
[dependencies]
|
||||
libtaos = { version = "0.4.2"}
|
||||
taos = { version = "*"}
|
||||
```
|
||||
|
||||
:::info
|
||||
Rust 连接器通过不同的特性区分不同的连接方式。如果要建立 REST 连接,需要开启 `rest` 特性:
|
||||
Rust 连接器通过不同的特性区分不同的连接方式。默认同时支持原生连接和 Websocket 连接,如果仅需要建立 Websocket 连接,可设置 `ws` 特性:
|
||||
|
||||
```toml
|
||||
libtaos = { version = "*", features = ["rest"] }
|
||||
taos = { version = "*", default-features = false, features = ["ws"] }
|
||||
```
|
||||
|
||||
:::
|
||||
|
|
|
@ -16,7 +16,7 @@ TDengine 采用类关系型数据模型,需要建库、建表。因此对于
|
|||
CREATE DATABASE power KEEP 365 DURATION 10 BUFFER 16 WAL_LEVEL 1;
|
||||
```
|
||||
|
||||
上述语句将创建一个名为 power 的库,这个库的数据将保留 365 天(超过 365 天将被自动删除),每 10 天一个数据文件,每个 VNode 的写入内存池的大小为 16 MB,对该数据库入会写 WAL 但不执行 FSYNC。详细的语法及参数请见 [数据库管理](/taos-sql/database) 章节。
|
||||
上述语句将创建一个名为 power 的库,这个库的数据将保留 365 天(超过 365 天将被自动删除),每 10 天一个数据文件,每个 VNode 的写入内存池的大小为 16 MB,对该数据库入会写 WAL 但不执行 FSYNC。详细的语法及参数请见 [数据库管理](../../taos-sql/database) 章节。
|
||||
|
||||
创建库之后,需要使用 SQL 命令 `USE` 将当前库切换过来,例如:
|
||||
|
||||
|
@ -35,13 +35,13 @@ USE power;
|
|||
|
||||
## 创建超级表
|
||||
|
||||
一个物联网系统,往往存在多种类型的设备,比如对于电网,存在智能电表、变压器、母线、开关等等。为便于多表之间的聚合,使用 TDengine, 需要对每个类型的数据采集点创建一个超级表。以 [表 1](/concept) 中的智能电表为例,可以使用如下的 SQL 命令创建超级表:
|
||||
一个物联网系统,往往存在多种类型的设备,比如对于电网,存在智能电表、变压器、母线、开关等等。为便于多表之间的聚合,使用 TDengine, 需要对每个类型的数据采集点创建一个超级表。以 [表 1](../../concept) 中的智能电表为例,可以使用如下的 SQL 命令创建超级表:
|
||||
|
||||
```sql
|
||||
CREATE STABLE meters (ts timestamp, current float, voltage int, phase float) TAGS (location binary(64), groupId int);
|
||||
```
|
||||
|
||||
与创建普通表一样,创建超级表时,需要提供表名(示例中为 meters),表结构 Schema,即数据列的定义。第一列必须为时间戳(示例中为 ts),其他列为采集的物理量(示例中为 current, voltage, phase),数据类型可以为整型、浮点型、字符串等。除此之外,还需要提供标签的 Schema (示例中为 location, groupId),标签的数据类型可以为整型、浮点型、字符串等。采集点的静态属性往往可以作为标签,比如采集点的地理位置、设备型号、设备组 ID、管理员 ID 等等。标签的 Schema 可以事后增加、删除、修改。具体定义以及细节请见 [TDengine SQL 的超级表管理](/taos-sql/stable) 章节。
|
||||
与创建普通表一样,创建超级表时,需要提供表名(示例中为 meters),表结构 Schema,即数据列的定义。第一列必须为时间戳(示例中为 ts),其他列为采集的物理量(示例中为 current, voltage, phase),数据类型可以为整型、浮点型、字符串等。除此之外,还需要提供标签的 Schema (示例中为 location, groupId),标签的数据类型可以为整型、浮点型、字符串等。采集点的静态属性往往可以作为标签,比如采集点的地理位置、设备型号、设备组 ID、管理员 ID 等等。标签的 Schema 可以事后增加、删除、修改。具体定义以及细节请见 [TDengine SQL 的超级表管理](../../taos-sql/stable) 章节。
|
||||
|
||||
每一种类型的数据采集点需要建立一个超级表,因此一个物联网系统,往往会有多个超级表。对于电网,我们就需要对智能电表、变压器、母线、开关等都建立一个超级表。在物联网中,一个设备就可能有多个数据采集点(比如一台风力发电的风机,有的采集点采集电流、电压等电参数,有的采集点采集温度、湿度、风向等环境参数),这个时候,对这一类型的设备,需要建立多张超级表。
|
||||
|
||||
|
@ -49,13 +49,13 @@ CREATE STABLE meters (ts timestamp, current float, voltage int, phase float) TAG
|
|||
|
||||
## 创建表
|
||||
|
||||
TDengine 对每个数据采集点需要独立建表。与标准的关系型数据库一样,一张表有表名,Schema,但除此之外,还可以带有一到多个标签。创建时,需要使用超级表做模板,同时指定标签的具体值。以 [表 1](/concept) 中的智能电表为例,可以使用如下的 SQL 命令建表:
|
||||
TDengine 对每个数据采集点需要独立建表。与标准的关系型数据库一样,一张表有表名,Schema,但除此之外,还可以带有一到多个标签。创建时,需要使用超级表做模板,同时指定标签的具体值。以 [表 1](../../concept) 中的智能电表为例,可以使用如下的 SQL 命令建表:
|
||||
|
||||
```sql
|
||||
CREATE TABLE d1001 USING meters TAGS ("California.SanFrancisco", 2);
|
||||
```
|
||||
|
||||
其中 d1001 是表名,meters 是超级表的表名,后面紧跟标签 Location 的具体标签值为 "California.SanFrancisco",标签 groupId 的具体标签值为 2。虽然在创建表时,需要指定标签值,但可以事后修改。详细细则请见 [TDengine SQL 的表管理](/taos-sql/table) 章节。
|
||||
其中 d1001 是表名,meters 是超级表的表名,后面紧跟标签 Location 的具体标签值为 "California.SanFrancisco",标签 groupId 的具体标签值为 2。虽然在创建表时,需要指定标签值,但可以事后修改。详细细则请见 [TDengine SQL 的表管理](../../taos-sql/table) 章节。
|
||||
|
||||
TDengine 建议将数据采集点的全局唯一 ID 作为表名(比如设备序列号)。但对于有的场景,并没有唯一的 ID,可以将多个 ID 组合成一个唯一的 ID。不建议将具有唯一性的 ID 作为标签值。
|
||||
|
||||
|
@ -69,7 +69,7 @@ INSERT INTO d1001 USING meters TAGS ("California.SanFrancisco", 2) VALUES (NOW,
|
|||
|
||||
上述 SQL 语句将记录`(NOW, 10.2, 219, 0.32)`插入表 d1001。如果表 d1001 还未创建,则使用超级表 meters 做模板自动创建,同时打上标签值 `"California.SanFrancisco", 2`。
|
||||
|
||||
关于自动建表的详细语法请参见 [插入记录时自动建表](/taos-sql/insert#插入记录时自动建表) 章节。
|
||||
关于自动建表的详细语法请参见 [插入记录时自动建表](../../taos-sql/insert#插入记录时自动建表) 章节。
|
||||
|
||||
## 多列模型 vs 单列模型
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ import PhpStmt from "./_php_stmt.mdx";
|
|||
INSERT INTO d1001 VALUES (ts1, 10.3, 219, 0.31);
|
||||
```
|
||||
|
||||
这里的`ts1`为Unix时间戳(Unix timestamp),允许插入的最老记录的时间戳,是相对于当前服务器时间,减去配置的 KEEP 值。时间戳详情规则参考 [TDengine SQL数据写入 关于时间戳一节](/taos-sql/insert)
|
||||
这里的`ts1`为Unix时间戳(Unix timestamp),允许插入的最老记录的时间戳,是相对于当前服务器时间,减去配置的 KEEP 值。时间戳详情规则参考 [TDengine SQL数据写入 关于时间戳一节](../../../taos-sql/insert)
|
||||
|
||||
### 一次写入多条
|
||||
|
||||
|
@ -43,7 +43,7 @@ TDengine 支持一次写入多条记录,比如下面这条命令就将两条
|
|||
INSERT INTO d1001 VALUES (ts1, 10.2, 220, 0.23) (ts2, 10.3, 218, 0.25);
|
||||
```
|
||||
|
||||
这里的`ts1`和`ts2`为Unix时间戳(Unix timestamp),允许插入的最老记录的时间戳,是相对于当前服务器时间,减去配置的 KEEP 值。时间戳详情规则参考 [TDengine SQL数据写入 关于时间戳一节](/taos-sql/insert)
|
||||
这里的`ts1`和`ts2`为Unix时间戳(Unix timestamp),允许插入的最老记录的时间戳,是相对于当前服务器时间,减去配置的 KEEP 值。时间戳详情规则参考 [TDengine SQL数据写入 关于时间戳一节](../../../taos-sql/insert)
|
||||
|
||||
### 一次写入多表
|
||||
|
||||
|
@ -53,9 +53,9 @@ TDengine 也支持一次向多个表写入数据,比如下面这条命令就
|
|||
INSERT INTO d1001 VALUES (ts1, 10.3, 219, 0.31) (ts2, 12.6, 218, 0.33) d1002 VALUES (ts3, 12.3, 221, 0.31);
|
||||
```
|
||||
|
||||
这里的`ts1`、`ts2`和`ts3`为Unix时间戳(Unix timestamp),允许插入的最老记录的时间戳,是相对于当前服务器时间,减去配置的 KEEP 值。时间戳详情规则参考 [TDengine SQL数据写入 关于时间戳一节](/taos-sql/insert)
|
||||
这里的`ts1`、`ts2`和`ts3`为Unix时间戳(Unix timestamp),允许插入的最老记录的时间戳,是相对于当前服务器时间,减去配置的 KEEP 值。时间戳详情规则参考 [TDengine SQL数据写入 关于时间戳一节](../../../taos-sql/insert)
|
||||
|
||||
详细的 SQL INSERT 语法规则参考 [TDengine SQL 的数据写入](/taos-sql/insert)。
|
||||
详细的 SQL INSERT 语法规则参考 [TDengine SQL 的数据写入](../../../taos-sql/insert)。
|
||||
|
||||
:::info
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ bin/kafka-topics.sh --bootstrap-server=localhost:9092 --describe
|
|||
|
||||
## 写入 TDengine
|
||||
|
||||
TDengine 支持 Sql 方式和 Schemaless 方式的数据写入,Sql 方式数据写入可以参考 [TDengine SQL 写入](/develop/insert-data/sql-writing/) 和 [TDengine 高效写入](/develop/insert-data/high-volume/)。Schemaless 方式数据写入可以参考 [TDengine Schemaless 写入](/reference/schemaless/) 文档。
|
||||
TDengine 支持 Sql 方式和 Schemaless 方式的数据写入,Sql 方式数据写入可以参考 [TDengine SQL 写入](../sql-writing/) 和 [TDengine 高效写入](../high-volume/)。Schemaless 方式数据写入可以参考 [TDengine Schemaless 写入](../../../reference/schemaless/) 文档。
|
||||
|
||||
## 示例代码
|
||||
|
||||
|
|
|
@ -37,15 +37,15 @@ meters,location=California.LosAngeles,groupid=2 current=13.4,voltage=223,phase=0
|
|||
- tag_set 中的所有的数据自动转化为 NCHAR 数据类型
|
||||
- field_set 中的每个数据项都需要对自身的数据类型进行描述, 比如 1.2f32 代表 FLOAT 类型的数值 1.2, 如果不带类型后缀会被当作 DOUBLE 处理
|
||||
- timestamp 支持多种时间精度。写入数据的时候需要用参数指定时间精度,支持从小时到纳秒的 6 种时间精度
|
||||
- 为了提高写入的效率,默认假设同一个超级表中 field_set 的顺序是一样的(第一条数据包含所有的 field,后面的数据按照这个顺序),如果顺序不一样,需要配置参数 smlDataFormat 为 false,否则,数据写入按照相同顺序写入,库中数据会异常。(3.0.1.3 之后的版本 smlDataFormat 默认为 false,从3.0.3.0开始,该配置废弃) [TDengine 无模式写入参考指南](/reference/schemaless/#无模式写入行协议)
|
||||
- 为了提高写入的效率,默认假设同一个超级表中 field_set 的顺序是一样的(第一条数据包含所有的 field,后面的数据按照这个顺序),如果顺序不一样,需要配置参数 smlDataFormat 为 false,否则,数据写入按照相同顺序写入,库中数据会异常。(3.0.1.3 之后的版本 smlDataFormat 默认为 false,从3.0.3.0开始,该配置废弃) [TDengine 无模式写入参考指南](../../../reference/schemaless/#无模式写入行协议)
|
||||
- 子表名生成规则
|
||||
- 默认产生的子表名是根据规则生成的唯一 ID 值。
|
||||
- 用户也可以通过在client端的 taos.cfg 里配置 smlAutoChildTableNameDelimiter 参数来指定连接标签之间的分隔符,连接起来后作为子表名。举例如下:配置 smlAutoChildTableNameDelimiter=-, 插入数据为 st,t0=cpu1,t1=4 c1=3 1626006833639000000 则创建的子表名为 cpu1-4。
|
||||
- 用户也可以通过在client端的 taos.cfg 里配置 smlChildTableName 参数来指定某个标签值作为子表名。该标签值应该具有全局唯一性。举例如下:假设有个标签名为tname, 配置 smlChildTableName=tname, 插入数据为 st,tname=cpu1,t1=4 c1=3 1626006833639000000 则创建的子表名为 cpu1。注意如果多行数据 tname 相同,但是后面的 tag_set 不同,则使用第一行自动建表时指定的 tag_set,其他的行会忽略)。[TDengine 无模式写入参考指南](/reference/schemaless/#无模式写入行协议)
|
||||
- 用户也可以通过在client端的 taos.cfg 里配置 smlChildTableName 参数来指定某个标签值作为子表名。该标签值应该具有全局唯一性。举例如下:假设有个标签名为tname, 配置 smlChildTableName=tname, 插入数据为 st,tname=cpu1,t1=4 c1=3 1626006833639000000 则创建的子表名为 cpu1。注意如果多行数据 tname 相同,但是后面的 tag_set 不同,则使用第一行自动建表时指定的 tag_set,其他的行会忽略)。[TDengine 无模式写入参考指南](../../../reference/schemaless/#无模式写入行协议)
|
||||
|
||||
:::
|
||||
|
||||
要了解更多可参考:[InfluxDB Line 协议官方文档](https://docs.influxdata.com/influxdb/v2.0/reference/syntax/line-protocol/) 和 [TDengine 无模式写入参考指南](/reference/schemaless/#无模式写入行协议)
|
||||
要了解更多可参考:[InfluxDB Line 协议官方文档](https://docs.influxdata.com/influxdb/v2.0/reference/syntax/line-protocol/) 和 [TDengine 无模式写入参考指南](../../../reference/schemaless/#无模式写入行协议)
|
||||
|
||||
## 示例代码
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ meters.current 1648432611250 11.3 location=California.LosAngeles groupid=3
|
|||
- 子表名生成规则
|
||||
- 默认产生的子表名是根据规则生成的唯一 ID 值。
|
||||
- 用户也可以通过在client端的 taos.cfg 里配置 smlAutoChildTableNameDelimiter 参数来指定连接标签之间的分隔符,连接起来后作为子表名。举例如下:配置 smlAutoChildTableNameDelimiter=-, 插入数据为 st,t0=cpu1,t1=4 c1=3 1626006833639000000 则创建的子表名为 cpu1-4。
|
||||
- 用户也可以通过在client端的 taos.cfg 里配置 smlChildTableName 参数来指定某个标签值作为子表名。该标签值应该具有全局唯一性。举例如下:假设有个标签名为tname, 配置 smlChildTableName=tname, 插入数据为 st,tname=cpu1,t1=4 c1=3 1626006833639000000 则创建的子表名为 cpu1。注意如果多行数据 tname 相同,但是后面的 tag_set 不同,则使用第一行自动建表时指定的 tag_set,其他的行会忽略)。[TDengine 无模式写入参考指南](/reference/schemaless/#无模式写入行协议)
|
||||
- 用户也可以通过在client端的 taos.cfg 里配置 smlChildTableName 参数来指定某个标签值作为子表名。该标签值应该具有全局唯一性。举例如下:假设有个标签名为tname, 配置 smlChildTableName=tname, 插入数据为 st,tname=cpu1,t1=4 c1=3 1626006833639000000 则创建的子表名为 cpu1。注意如果多行数据 tname 相同,但是后面的 tag_set 不同,则使用第一行自动建表时指定的 tag_set,其他的行会忽略)。[TDengine 无模式写入参考指南](../../../reference/schemaless/#无模式写入行协议)
|
||||
|
||||
参考 [OpenTSDB Telnet API 文档](http://opentsdb.net/docs/build/html/api_telnet/put.html)。
|
||||
|
||||
|
|
|
@ -50,7 +50,7 @@ OpenTSDB JSON 格式协议采用一个 JSON 字符串表示一行或多行数据
|
|||
- 子表名生成规则
|
||||
- 默认产生的子表名是根据规则生成的唯一 ID 值。
|
||||
- 用户也可以通过在client端的 taos.cfg 里配置 smlAutoChildTableNameDelimiter 参数来指定连接标签之间的分隔符,连接起来后作为子表名。举例如下:配置 smlAutoChildTableNameDelimiter=-, 插入数据为 st,t0=cpu1,t1=4 c1=3 1626006833639000000 则创建的子表名为 cpu1-4。
|
||||
- 用户也可以通过在client端的 taos.cfg 里配置 smlChildTableName 参数来指定某个标签值作为子表名。该标签值应该具有全局唯一性。举例如下:假设有个标签名为tname, 配置 smlChildTableName=tname, 插入数据为 st,tname=cpu1,t1=4 c1=3 1626006833639000000 则创建的子表名为 cpu1。注意如果多行数据 tname 相同,但是后面的 tag_set 不同,则使用第一行自动建表时指定的 tag_set,其他的行会忽略)。[TDengine 无模式写入参考指南](/reference/schemaless/#无模式写入行协议)
|
||||
- 用户也可以通过在client端的 taos.cfg 里配置 smlChildTableName 参数来指定某个标签值作为子表名。该标签值应该具有全局唯一性。举例如下:假设有个标签名为tname, 配置 smlChildTableName=tname, 插入数据为 st,tname=cpu1,t1=4 c1=3 1626006833639000000 则创建的子表名为 cpu1。注意如果多行数据 tname 相同,但是后面的 tag_set 不同,则使用第一行自动建表时指定的 tag_set,其他的行会忽略)。[TDengine 无模式写入参考指南](../../../reference/schemaless/#无模式写入行协议)
|
||||
|
||||
:::
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ import CAsync from "./_c_async.mdx";
|
|||
TDengine 采用 SQL 作为查询语言。应用程序可以通过 REST API 或连接器发送 SQL 语句,用户还可以通过 TDengine 命令行工具 taos 手动执行 SQL 即席查询(Ad-Hoc Query)。TDengine 支持如下查询功能:
|
||||
|
||||
- 单列、多列数据查询
|
||||
- 标签和数值的多种过滤条件:>, <, =, <\>, like 等
|
||||
- 标签和数值的多种过滤条件:>, \<, =, \<>, like 等
|
||||
- 聚合结果的分组(Group by)、排序(Order by)、约束输出(Limit/Offset)
|
||||
- 时间窗口(Interval)、会话窗口(Session)和状态窗口(State_window)等窗口切分聚合查询
|
||||
- 数值列及聚合结果的四则运算
|
||||
|
@ -128,7 +128,7 @@ Query OK, 6 rows in database (0.005515s)
|
|||
|
||||
### 查询数据
|
||||
|
||||
在 [SQL 写入](/develop/insert-data/sql-writing) 一章,我们创建了 power 数据库,并向 meters 表写入了一些数据,以下示例代码展示如何查询这个表的数据。
|
||||
在 [SQL 写入](../insert-data/sql-writing) 一章,我们创建了 power 数据库,并向 meters 表写入了一些数据,以下示例代码展示如何查询这个表的数据。
|
||||
|
||||
<Tabs defaultValue="java" groupId="lang">
|
||||
<TabItem label="Java" value="java">
|
||||
|
@ -160,7 +160,7 @@ Query OK, 6 rows in database (0.005515s)
|
|||
:::note
|
||||
|
||||
1. 无论是使用 REST 连接还是原生连接的连接器,以上示例代码都能正常工作。
|
||||
2. 唯一需要注意的是:由于 REST 接口无状态, 不能使用 `use db` 语句来切换数据库。除了在 REST 参数中指定数据库以外也可以在 SQL 语句中使用 <db_name>.<table_name> 来指定数据库。
|
||||
2. 唯一需要注意的是:由于 REST 接口无状态, 不能使用 `use db` 语句来切换数据库。除了在 REST 参数中指定数据库以外也可以在 SQL 语句中使用 \<db_name>.\<table_name> 来指定数据库。
|
||||
|
||||
:::
|
||||
|
||||
|
|
|
@ -261,7 +261,7 @@ impl AsAsyncConsumer for Consumer
|
|||
async fn unsubscribe(self);
|
||||
```
|
||||
|
||||
可在 <https://docs.rs/taos> 上查看详细 API 说明。
|
||||
可在 \<https://docs.rs/taos> 上查看详细 API 说明。
|
||||
|
||||
</TabItem>
|
||||
|
||||
|
@ -848,7 +848,7 @@ consumer.Close();
|
|||
2023/09/22 00:00:00.000
|
||||
2023/09/22 00:00:05.000
|
||||
2023/09/22 00:00:08.000
|
||||
```
|
||||
```
|
||||
则订阅出第一条数据 5s 后返回第二条数据,获取第二条数据 3s 后返回第三条数据。
|
||||
- 仅查询订阅支持数据回放
|
||||
- 回放需要保证独立时间线
|
||||
|
|
|
@ -195,7 +195,7 @@ typedef struct SUdfInterBuf {
|
|||
```
|
||||
数据结构说明如下:
|
||||
|
||||
- SUdfDataBlock 数据块包含行数 numOfRows 和列数 numCols。udfCols[i] (0 <= i <= numCols-1)表示每一列数据,类型为SUdfColumn*。
|
||||
- SUdfDataBlock 数据块包含行数 numOfRows 和列数 numCols。udfCols[i] (0 \<= i \<= numCols-1)表示每一列数据,类型为SUdfColumn*。
|
||||
- SUdfColumn 包含列的数据类型定义 colMeta 和列的数据 colData。
|
||||
- SUdfColumnMeta 成员定义同 taos.h 数据类型定义。
|
||||
- SUdfColumnData 数据可以变长,varLenCol 定义变长数据,fixLenCol 定义定长数据。
|
||||
|
@ -396,7 +396,7 @@ def finish(buf: bytes) -> output_type:
|
|||
1. 定义一个只接收一个整数的标量函数: 输入 n, 输出 ln(n^2 + 1)。
|
||||
2. 定义一个接收 n 个整数的标量函数, 输入 (x1, x2, ..., xn), 输出每个值和它们的序号的乘积的和: x1 + 2 * x2 + ... + n * xn。
|
||||
3. 定义一个标量函数,输入一个时间戳,输出距离这个时间最近的下一个周日。完成这个函数要用到第三方库 moment。我们在这个示例中讲解使用第三方库的注意事项。
|
||||
4. 定义一个聚合函数,计算某一列最大值和最小值的差, 也就是实现 TDengien 内置的 spread 函数。
|
||||
4. 定义一个聚合函数,计算某一列最大值和最小值的差, 也就是实现 TDengine 内置的 spread 函数。
|
||||
同时也包含大量实用的 debug 技巧。
|
||||
本文假设你用的是 Linux 系统,且已安装好了 TDengine 3.0.4.0+ 和 Python 3.7+。
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ description: 让开发者能够快速上手的指南
|
|||
7. 在很多场景下(如车辆管理),应用需要获取每个数据采集点的最新状态,那么建议你采用 TDengine 的 Cache 功能,而不用单独部署 Redis 等缓存软件。
|
||||
8. 如果你发现 TDengine 的函数无法满足你的要求,那么你可以使用用户自定义函数(UDF)来解决问题。
|
||||
|
||||
本部分内容就是按照上述顺序组织的。为便于理解,TDengine 为每个功能和每个支持的编程语言都提供了示例代码。如果你希望深入了解 SQL 的使用,需要查看[SQL 手册](/taos-sql/)。如果想更深入地了解各连接器的使用,请阅读[连接器参考指南](../connector/)。如果还希望想将 TDengine 与第三方系统集成起来,比如 Grafana, 请参考[第三方工具](../third-party/)。
|
||||
本部分内容就是按照上述顺序组织的。为便于理解,TDengine 为每个功能和每个支持的编程语言都提供了示例代码。如果你希望深入了解 SQL 的使用,需要查看[SQL 手册](../taos-sql/)。如果想更深入地了解各连接器的使用,请阅读[连接器参考指南](../connector/)。如果还希望想将 TDengine 与第三方系统集成起来,比如 Grafana, 请参考[第三方工具](../third-party/)。
|
||||
|
||||
如果在开发过程中遇到任何问题,请点击每个页面下方的["反馈问题"](https://github.com/taosdata/TDengine/issues/new/choose), 在 GitHub 上直接递交 Issue。
|
||||
|
||||
|
|
|
@ -69,7 +69,7 @@ curl -L -H "Authorization: Basic cm9vdDp0YW9zZGF0YQ==" \
|
|||
## HTTP 请求格式
|
||||
|
||||
```text
|
||||
http://<fqdn>:<port>/rest/sql/[db_name][?tz=timezone[&req_id=req_id]]
|
||||
http://<fqdn>:<port>/rest/sql/[db_name][?tz=timezone[&req_id=req_id][&row_with_meta=true]]
|
||||
```
|
||||
|
||||
参数说明:
|
||||
|
@ -79,6 +79,7 @@ http://<fqdn>:<port>/rest/sql/[db_name][?tz=timezone[&req_id=req_id]]
|
|||
- db_name: 可选参数,指定本次所执行的 SQL 语句的默认数据库库名。
|
||||
- tz: 可选参数,指定返回时间的时区,遵照 IANA Time Zone 规则,如 `America/New_York`。
|
||||
- req_id: 可选参数,指定请求 id,可以用于 tracing。
|
||||
- row_with_meta: 可选参数,指定是否每行数据都携带列名,缺省为 false。(3.3.2.0 版本开始支持)
|
||||
|
||||
例如:`http://h1.taos.com:6041/rest/sql/test` 是指向地址为 `h1.taos.com:6041` 的 URL,并将默认使用的数据库库名设置为 `test`。
|
||||
|
||||
|
@ -101,13 +102,13 @@ HTTP 请求的 BODY 里就是一个完整的 SQL 语句,SQL 语句中的数据
|
|||
使用 `curl` 通过自定义身份认证方式来发起一个 HTTP Request,语法如下:
|
||||
|
||||
```bash
|
||||
curl -L -H "Authorization: Basic <TOKEN>" -d "<SQL>" <ip>:<PORT>/rest/sql/[db_name][?tz=timezone[&req_id=req_id]]
|
||||
curl -L -H "Authorization: Basic <TOKEN>" -d "<SQL>" <ip>:<PORT>/rest/sql/[db_name][?tz=timezone[&req_id=req_id][&row_with_meta=true]]
|
||||
```
|
||||
|
||||
或者,
|
||||
|
||||
```bash
|
||||
curl -L -u username:password -d "<SQL>" <ip>:<PORT>/rest/sql/[db_name][?tz=timezone[&req_id=req_id]]
|
||||
curl -L -u username:password -d "<SQL>" <ip>:<PORT>/rest/sql/[db_name][?tz=timezone[&req_id=req_id][&row_with_meta=true]]
|
||||
```
|
||||
|
||||
其中,`TOKEN` 为 `{username}:{password}` 经过 Base64 编码之后的字符串,例如 `root:taosdata` 编码后为 `cm9vdDp0YW9zZGF0YQ==`。
|
||||
|
@ -331,6 +332,82 @@ curl --location 'http://<fqdn>:<port>/rest/sql' \
|
|||
- code:(`int`)错误码。
|
||||
- desc:(`string`)错误描述。
|
||||
|
||||
#### 返回key-value形式数据
|
||||
|
||||
当指定 url 参数 `row_with_meta=true` 时,返回的 data 中的数据会从数组的形式变成对象的形式,对象的 key 为列名,value 为数据,如下所示:
|
||||
|
||||
插入数据返回示例
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 0,
|
||||
"column_meta": [
|
||||
[
|
||||
"affected_rows",
|
||||
"INT",
|
||||
4
|
||||
]
|
||||
],
|
||||
"data": [
|
||||
{
|
||||
"affected_rows": 1
|
||||
}
|
||||
],
|
||||
"rows": 1
|
||||
}
|
||||
```
|
||||
|
||||
查询数据返回示例
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 0,
|
||||
"column_meta": [
|
||||
[
|
||||
"ts",
|
||||
"TIMESTAMP",
|
||||
8
|
||||
],
|
||||
[
|
||||
"current",
|
||||
"FLOAT",
|
||||
4
|
||||
],
|
||||
[
|
||||
"voltage",
|
||||
"INT",
|
||||
4
|
||||
],
|
||||
[
|
||||
"phase",
|
||||
"FLOAT",
|
||||
4
|
||||
],
|
||||
[
|
||||
"groupid",
|
||||
"INT",
|
||||
4
|
||||
],
|
||||
[
|
||||
"location",
|
||||
"VARCHAR",
|
||||
24
|
||||
]
|
||||
],
|
||||
"data": [
|
||||
{
|
||||
"ts": "2017-07-14T02:40:00.000Z",
|
||||
"current": -2.498076,
|
||||
"voltage": 0,
|
||||
"phase": -0.846025,
|
||||
"groupid": 8,
|
||||
"location": "California.Sunnyvale"
|
||||
}
|
||||
],
|
||||
"rows": 1
|
||||
}
|
||||
```
|
||||
|
||||
## 自定义授权码
|
||||
|
||||
HTTP 请求中需要带有授权码 `<TOKEN>`,用于身份识别。授权码通常由管理员提供,可简单的通过发送 `HTTP GET` 请求来获取授权码,操作如下:
|
||||
|
@ -569,4 +646,4 @@ curl http://192.168.0.1:6041/rest/login/root/taosdata
|
|||
|
||||
## 参考
|
||||
|
||||
[taosAdapter](/reference/taosadapter/)
|
||||
[taosAdapter](../../reference/taosadapter/)
|
||||
|
|
|
@ -274,7 +274,7 @@ int taos_print_row(char *str, TAOS_ROW row, TAOS_FIELD *fields, int num_fields)
|
|||
|
||||
- database,len为用户在外面申请的空间,内部会把当前db赋值到database里。
|
||||
- 只要是没有正常把db名赋值到database中(包括截断),返回错误,返回值为-1,然后用户可以通过 taos_errstr(NULL) 来获取错误提示。
|
||||
- 如果,database == NULL 或者 len<=0 返回错误,required里保存存储db需要的空间(包含最后的'\0')
|
||||
- 如果,database == NULL 或者 len\<=0 返回错误,required里保存存储db需要的空间(包含最后的'\0')
|
||||
- 如果,len 小于 存储db需要的空间(包含最后的'\0'),返回错误,database里赋值截断的数据,以'\0'结尾。
|
||||
- 如果,len 大于等于 存储db需要的空间(包含最后的'\0'),返回正常0,database里赋值以'\0‘结尾的db名。
|
||||
|
||||
|
@ -472,7 +472,7 @@ TDengine 的异步 API 均采用非阻塞调用模式。应用程序可以用多
|
|||
|
||||
### 无模式(schemaless)写入 API
|
||||
|
||||
除了使用 SQL 方式或者使用参数绑定 API 写入数据外,还可以使用 Schemaless 的方式完成写入。Schemaless 可以免于预先创建超级表/数据子表的数据结构,而是可以直接写入数据,TDengine 系统会根据写入的数据内容自动创建和维护所需要的表结构。Schemaless 的使用方式详见 [Schemaless 写入](/reference/schemaless/) 章节,这里介绍与之配套使用的 C/C++ API。
|
||||
除了使用 SQL 方式或者使用参数绑定 API 写入数据外,还可以使用 Schemaless 的方式完成写入。Schemaless 可以免于预先创建超级表/数据子表的数据结构,而是可以直接写入数据,TDengine 系统会根据写入的数据内容自动创建和维护所需要的表结构。Schemaless 的使用方式详见 [Schemaless 写入](../../reference/schemaless/) 章节,这里介绍与之配套使用的 C/C++ API。
|
||||
|
||||
- `TAOS_RES* taos_schemaless_insert(TAOS* taos, const char* lines[], int numLines, int protocol, int precision)`
|
||||
|
||||
|
|
|
@ -8,20 +8,23 @@ title: TDengine Go Connector
|
|||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
import Preparation from "./_preparation.mdx"
|
||||
import GoInsert from "../07-develop/03-insert-data/_go_sql.mdx"
|
||||
import GoInfluxLine from "../07-develop/03-insert-data/_go_line.mdx"
|
||||
import GoOpenTSDBTelnet from "../07-develop/03-insert-data/_go_opts_telnet.mdx"
|
||||
import GoOpenTSDBJson from "../07-develop/03-insert-data/_go_opts_json.mdx"
|
||||
import GoQuery from "../07-develop/04-query-data/_go.mdx"
|
||||
import RequestId from "./_request_id.mdx";
|
||||
|
||||
`driver-go` 是 TDengine 的官方 Go 语言连接器,实现了 Go 语言 [database/sql](https://golang.org/pkg/database/sql/) 包的接口。Go 开发人员可以通过它开发存取 TDengine 集群数据的应用软件。
|
||||
|
||||
`driver-go` 提供两种建立连接的方式。一种是**原生连接**,它通过 TDengine 客户端驱动程序(taosc)原生连接 TDengine 运行实例,支持数据写入、查询、订阅、schemaless 接口和参数绑定接口等功能。另外一种是 **REST 连接**,它通过 taosAdapter 提供的 REST 接口连接 TDengine 运行实例。REST 连接实现的功能特性集合和原生连接有少量不同。
|
||||
## 连接方式
|
||||
|
||||
本文介绍如何安装 `driver-go`,并通过 `driver-go` 连接 TDengine 集群、进行数据查询、数据写入等基本操作。
|
||||
`driver-go` 提供三种建立连接的方式。
|
||||
|
||||
`driver-go` 的源码托管在 [GitHub](https://github.com/taosdata/driver-go)。
|
||||
* **原生连接**,通过 TDengine 客户端驱动程序(taosc)原生连接 TDengine 实例,支持数据写入、查询、数据订阅、schemaless 接口和参数绑定接口等功能。
|
||||
* **REST 连接**,通过 taosAdapter 提供的 HTTP 接口连接 TDengine 实例,不支持 schemaless 和数据订阅等特性。
|
||||
* **Websocket 连接**,通过 taosAdapter 提供的 Websocket 接口连接 TDengine 实例,WebSocket 连接实现的功能集合和原生连接有少量不同。
|
||||
|
||||
连接方式的详细介绍请参考:[连接器建立连接的方式](../../develop/connect/#连接器建立连接的方式)
|
||||
|
||||
## 兼容性
|
||||
|
||||
支持最低 Go 版本 1.14,建议使用最新 Go 版本
|
||||
|
||||
## 支持的平台
|
||||
|
||||
|
@ -238,45 +241,27 @@ Go 连接器不支持此功能
|
|||
### 创建数据库和表
|
||||
|
||||
```go
|
||||
var taosDSN = "root:taosdata@tcp(localhost:6030)/"
|
||||
taos, err := sql.Open("taosSql", taosDSN)
|
||||
if err != nil {
|
||||
log.Fatalln("failed to connect TDengine, err:", err)
|
||||
}
|
||||
defer taos.Close()
|
||||
_, err := taos.Exec("CREATE DATABASE power")
|
||||
if err != nil {
|
||||
log.Fatalln("failed to create database, err:", err)
|
||||
}
|
||||
_, err = taos.Exec("CREATE STABLE power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (location BINARY(64), groupId INT)")
|
||||
if err != nil {
|
||||
log.Fatalln("failed to create stable, err:", err)
|
||||
}
|
||||
{{#include docs/examples/go/demo/query/main.go:create_db_and_table}}
|
||||
```
|
||||
|
||||
### 插入数据
|
||||
|
||||
<GoInsert />
|
||||
```go
|
||||
{{#include docs/examples/go/demo/query/main.go:insert_data}}
|
||||
```
|
||||
|
||||
### 查询数据
|
||||
|
||||
<GoQuery />
|
||||
```go
|
||||
{{#include docs/examples/go/demo/query/main.go:query_data}}
|
||||
```
|
||||
|
||||
### 执行带有 reqId 的 SQL
|
||||
|
||||
此 reqId 可用于请求链路追踪。
|
||||
<RequestId />
|
||||
|
||||
```go
|
||||
db, err := sql.Open("taosSql", "root:taosdata@tcp(localhost:6030)/")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer db.Close()
|
||||
ctx := context.WithValue(context.Background(), common.ReqIDKey, common.GetReqID())
|
||||
_, err = db.ExecContext(ctx, "create database if not exists example_taos_sql")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
{{#include docs/examples/go/demo/query/main.go:with_reqid}}
|
||||
```
|
||||
|
||||
### 通过参数绑定写入数据
|
||||
|
@ -285,375 +270,14 @@ if err != nil {
|
|||
<TabItem value="native" label="原生连接">
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/taosdata/driver-go/v3/af"
|
||||
"github.com/taosdata/driver-go/v3/common"
|
||||
"github.com/taosdata/driver-go/v3/common/param"
|
||||
)
|
||||
|
||||
func main() {
|
||||
db, err := af.Open("", "root", "taosdata", "", 0)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer db.Close()
|
||||
_, err = db.Exec("create database if not exists example_stmt")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
_, err = db.Exec("create table if not exists example_stmt.tb1(ts timestamp," +
|
||||
"c1 bool," +
|
||||
"c2 tinyint," +
|
||||
"c3 smallint," +
|
||||
"c4 int," +
|
||||
"c5 bigint," +
|
||||
"c6 tinyint unsigned," +
|
||||
"c7 smallint unsigned," +
|
||||
"c8 int unsigned," +
|
||||
"c9 bigint unsigned," +
|
||||
"c10 float," +
|
||||
"c11 double," +
|
||||
"c12 binary(20)," +
|
||||
"c13 nchar(20)" +
|
||||
")")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
stmt := db.InsertStmt()
|
||||
err = stmt.Prepare("insert into example_stmt.tb1 values(?,?,?,?,?,?,?,?,?,?,?,?,?,?)")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
now := time.Now()
|
||||
params := make([]*param.Param, 14)
|
||||
params[0] = param.NewParam(2).
|
||||
AddTimestamp(now, common.PrecisionMilliSecond).
|
||||
AddTimestamp(now.Add(time.Second), common.PrecisionMilliSecond)
|
||||
params[1] = param.NewParam(2).AddBool(true).AddNull()
|
||||
params[2] = param.NewParam(2).AddTinyint(2).AddNull()
|
||||
params[3] = param.NewParam(2).AddSmallint(3).AddNull()
|
||||
params[4] = param.NewParam(2).AddInt(4).AddNull()
|
||||
params[5] = param.NewParam(2).AddBigint(5).AddNull()
|
||||
params[6] = param.NewParam(2).AddUTinyint(6).AddNull()
|
||||
params[7] = param.NewParam(2).AddUSmallint(7).AddNull()
|
||||
params[8] = param.NewParam(2).AddUInt(8).AddNull()
|
||||
params[9] = param.NewParam(2).AddUBigint(9).AddNull()
|
||||
params[10] = param.NewParam(2).AddFloat(10).AddNull()
|
||||
params[11] = param.NewParam(2).AddDouble(11).AddNull()
|
||||
params[12] = param.NewParam(2).AddBinary([]byte("binary")).AddNull()
|
||||
params[13] = param.NewParam(2).AddNchar("nchar").AddNull()
|
||||
|
||||
paramTypes := param.NewColumnType(14).
|
||||
AddTimestamp().
|
||||
AddBool().
|
||||
AddTinyint().
|
||||
AddSmallint().
|
||||
AddInt().
|
||||
AddBigint().
|
||||
AddUTinyint().
|
||||
AddUSmallint().
|
||||
AddUInt().
|
||||
AddUBigint().
|
||||
AddFloat().
|
||||
AddDouble().
|
||||
AddBinary(6).
|
||||
AddNchar(5)
|
||||
err = stmt.BindParam(params, paramTypes)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = stmt.AddBatch()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = stmt.Execute()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = stmt.Close()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
// select * from example_stmt.tb1
|
||||
}
|
||||
{{#include docs/examples/go/demo/stmt/main.go}}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="WebSocket" label="WebSocket 连接">
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/taosdata/driver-go/v3/common"
|
||||
"github.com/taosdata/driver-go/v3/common/param"
|
||||
_ "github.com/taosdata/driver-go/v3/taosRestful"
|
||||
"github.com/taosdata/driver-go/v3/ws/stmt"
|
||||
)
|
||||
|
||||
func main() {
|
||||
db, err := sql.Open("taosRestful", "root:taosdata@http(localhost:6041)/")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer db.Close()
|
||||
prepareEnv(db)
|
||||
|
||||
config := stmt.NewConfig("ws://127.0.0.1:6041/rest/stmt", 0)
|
||||
config.SetConnectUser("root")
|
||||
config.SetConnectPass("taosdata")
|
||||
config.SetConnectDB("example_ws_stmt")
|
||||
config.SetMessageTimeout(common.DefaultMessageTimeout)
|
||||
config.SetWriteWait(common.DefaultWriteWait)
|
||||
config.SetErrorHandler(func(connector *stmt.Connector, err error) {
|
||||
panic(err)
|
||||
})
|
||||
config.SetCloseHandler(func() {
|
||||
fmt.Println("stmt connector closed")
|
||||
})
|
||||
|
||||
connector, err := stmt.NewConnector(config)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
now := time.Now()
|
||||
{
|
||||
stmt, err := connector.Init()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = stmt.Prepare("insert into ? using all_json tags(?) values(?,?,?,?,?,?,?,?,?,?,?,?,?,?)")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = stmt.SetTableName("tb1")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = stmt.SetTags(param.NewParam(1).AddJson([]byte(`{"tb":1}`)), param.NewColumnType(1).AddJson(0))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
params := []*param.Param{
|
||||
param.NewParam(3).AddTimestamp(now, 0).AddTimestamp(now.Add(time.Second), 0).AddTimestamp(now.Add(time.Second*2), 0),
|
||||
param.NewParam(3).AddBool(true).AddNull().AddBool(true),
|
||||
param.NewParam(3).AddTinyint(1).AddNull().AddTinyint(1),
|
||||
param.NewParam(3).AddSmallint(1).AddNull().AddSmallint(1),
|
||||
param.NewParam(3).AddInt(1).AddNull().AddInt(1),
|
||||
param.NewParam(3).AddBigint(1).AddNull().AddBigint(1),
|
||||
param.NewParam(3).AddUTinyint(1).AddNull().AddUTinyint(1),
|
||||
param.NewParam(3).AddUSmallint(1).AddNull().AddUSmallint(1),
|
||||
param.NewParam(3).AddUInt(1).AddNull().AddUInt(1),
|
||||
param.NewParam(3).AddUBigint(1).AddNull().AddUBigint(1),
|
||||
param.NewParam(3).AddFloat(1).AddNull().AddFloat(1),
|
||||
param.NewParam(3).AddDouble(1).AddNull().AddDouble(1),
|
||||
param.NewParam(3).AddBinary([]byte("test_binary")).AddNull().AddBinary([]byte("test_binary")),
|
||||
param.NewParam(3).AddNchar("test_nchar").AddNull().AddNchar("test_nchar"),
|
||||
}
|
||||
paramTypes := param.NewColumnType(14).
|
||||
AddTimestamp().
|
||||
AddBool().
|
||||
AddTinyint().
|
||||
AddSmallint().
|
||||
AddInt().
|
||||
AddBigint().
|
||||
AddUTinyint().
|
||||
AddUSmallint().
|
||||
AddUInt().
|
||||
AddUBigint().
|
||||
AddFloat().
|
||||
AddDouble().
|
||||
AddBinary(0).
|
||||
AddNchar(0)
|
||||
err = stmt.BindParam(params, paramTypes)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = stmt.AddBatch()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = stmt.Exec()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
affected := stmt.GetAffectedRows()
|
||||
fmt.Println("all_json affected rows:", affected)
|
||||
err = stmt.Close()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
{
|
||||
stmt, err := connector.Init()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = stmt.Prepare("insert into ? using all_all tags(?,?,?,?,?,?,?,?,?,?,?,?,?,?) values(?,?,?,?,?,?,?,?,?,?,?,?,?,?)")
|
||||
err = stmt.SetTableName("tb1")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
err = stmt.SetTableName("tb2")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = stmt.SetTags(
|
||||
param.NewParam(14).
|
||||
AddTimestamp(now, 0).
|
||||
AddBool(true).
|
||||
AddTinyint(2).
|
||||
AddSmallint(2).
|
||||
AddInt(2).
|
||||
AddBigint(2).
|
||||
AddUTinyint(2).
|
||||
AddUSmallint(2).
|
||||
AddUInt(2).
|
||||
AddUBigint(2).
|
||||
AddFloat(2).
|
||||
AddDouble(2).
|
||||
AddBinary([]byte("tb2")).
|
||||
AddNchar("tb2"),
|
||||
param.NewColumnType(14).
|
||||
AddTimestamp().
|
||||
AddBool().
|
||||
AddTinyint().
|
||||
AddSmallint().
|
||||
AddInt().
|
||||
AddBigint().
|
||||
AddUTinyint().
|
||||
AddUSmallint().
|
||||
AddUInt().
|
||||
AddUBigint().
|
||||
AddFloat().
|
||||
AddDouble().
|
||||
AddBinary(0).
|
||||
AddNchar(0),
|
||||
)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
params := []*param.Param{
|
||||
param.NewParam(3).AddTimestamp(now, 0).AddTimestamp(now.Add(time.Second), 0).AddTimestamp(now.Add(time.Second*2), 0),
|
||||
param.NewParam(3).AddBool(true).AddNull().AddBool(true),
|
||||
param.NewParam(3).AddTinyint(1).AddNull().AddTinyint(1),
|
||||
param.NewParam(3).AddSmallint(1).AddNull().AddSmallint(1),
|
||||
param.NewParam(3).AddInt(1).AddNull().AddInt(1),
|
||||
param.NewParam(3).AddBigint(1).AddNull().AddBigint(1),
|
||||
param.NewParam(3).AddUTinyint(1).AddNull().AddUTinyint(1),
|
||||
param.NewParam(3).AddUSmallint(1).AddNull().AddUSmallint(1),
|
||||
param.NewParam(3).AddUInt(1).AddNull().AddUInt(1),
|
||||
param.NewParam(3).AddUBigint(1).AddNull().AddUBigint(1),
|
||||
param.NewParam(3).AddFloat(1).AddNull().AddFloat(1),
|
||||
param.NewParam(3).AddDouble(1).AddNull().AddDouble(1),
|
||||
param.NewParam(3).AddBinary([]byte("test_binary")).AddNull().AddBinary([]byte("test_binary")),
|
||||
param.NewParam(3).AddNchar("test_nchar").AddNull().AddNchar("test_nchar"),
|
||||
}
|
||||
paramTypes := param.NewColumnType(14).
|
||||
AddTimestamp().
|
||||
AddBool().
|
||||
AddTinyint().
|
||||
AddSmallint().
|
||||
AddInt().
|
||||
AddBigint().
|
||||
AddUTinyint().
|
||||
AddUSmallint().
|
||||
AddUInt().
|
||||
AddUBigint().
|
||||
AddFloat().
|
||||
AddDouble().
|
||||
AddBinary(0).
|
||||
AddNchar(0)
|
||||
err = stmt.BindParam(params, paramTypes)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = stmt.AddBatch()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = stmt.Exec()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
affected := stmt.GetAffectedRows()
|
||||
fmt.Println("all_all affected rows:", affected)
|
||||
err = stmt.Close()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func prepareEnv(db *sql.DB) {
|
||||
steps := []string{
|
||||
"create database example_ws_stmt",
|
||||
"create table example_ws_stmt.all_json(ts timestamp," +
|
||||
"c1 bool," +
|
||||
"c2 tinyint," +
|
||||
"c3 smallint," +
|
||||
"c4 int," +
|
||||
"c5 bigint," +
|
||||
"c6 tinyint unsigned," +
|
||||
"c7 smallint unsigned," +
|
||||
"c8 int unsigned," +
|
||||
"c9 bigint unsigned," +
|
||||
"c10 float," +
|
||||
"c11 double," +
|
||||
"c12 binary(20)," +
|
||||
"c13 nchar(20)" +
|
||||
")" +
|
||||
"tags(t json)",
|
||||
"create table example_ws_stmt.all_all(" +
|
||||
"ts timestamp," +
|
||||
"c1 bool," +
|
||||
"c2 tinyint," +
|
||||
"c3 smallint," +
|
||||
"c4 int," +
|
||||
"c5 bigint," +
|
||||
"c6 tinyint unsigned," +
|
||||
"c7 smallint unsigned," +
|
||||
"c8 int unsigned," +
|
||||
"c9 bigint unsigned," +
|
||||
"c10 float," +
|
||||
"c11 double," +
|
||||
"c12 binary(20)," +
|
||||
"c13 nchar(20)" +
|
||||
")" +
|
||||
"tags(" +
|
||||
"tts timestamp," +
|
||||
"tc1 bool," +
|
||||
"tc2 tinyint," +
|
||||
"tc3 smallint," +
|
||||
"tc4 int," +
|
||||
"tc5 bigint," +
|
||||
"tc6 tinyint unsigned," +
|
||||
"tc7 smallint unsigned," +
|
||||
"tc8 int unsigned," +
|
||||
"tc9 bigint unsigned," +
|
||||
"tc10 float," +
|
||||
"tc11 double," +
|
||||
"tc12 binary(20)," +
|
||||
"tc13 nchar(20))",
|
||||
}
|
||||
for _, step := range steps {
|
||||
_, err := db.Exec(step)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{{#include docs/examples/go/demo/stmtws/main.go}}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
|
@ -665,98 +289,14 @@ func prepareEnv(db *sql.DB) {
|
|||
<TabItem value="native" label="原生连接">
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/taosdata/driver-go/v3/af"
|
||||
)
|
||||
|
||||
func main() {
|
||||
conn, err := af.Open("localhost", "root", "taosdata", "", 6030)
|
||||
if err != nil {
|
||||
fmt.Println("fail to connect, err:", err)
|
||||
}
|
||||
defer conn.Close()
|
||||
_, err = conn.Exec("create database if not exists example")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
_, err = conn.Exec("use example")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
influxdbData := "st,t1=3i64,t2=4f64,t3=\"t3\" c1=3i64,c3=L\"passit\",c2=false,c4=4f64 1626006833639000000"
|
||||
err = conn.InfluxDBInsertLines([]string{influxdbData}, "ns")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
telnetData := "stb0_0 1626006833 4 host=host0 interface=eth0"
|
||||
err = conn.OpenTSDBInsertTelnetLines([]string{telnetData})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
jsonData := "{\"metric\": \"meter_current\",\"timestamp\": 1626846400,\"value\": 10.3, \"tags\": {\"groupid\": 2, \"location\": \"California.SanFrancisco\", \"id\": \"d1001\"}}"
|
||||
err = conn.OpenTSDBInsertJsonPayload(jsonData)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
{{#include docs/examples/go/demo/sml/main.go}}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="WebSocket" label="WebSocket 连接">
|
||||
|
||||
```go
|
||||
import (
|
||||
"database/sql"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"github.com/taosdata/driver-go/v3/common"
|
||||
_ "github.com/taosdata/driver-go/v3/taosWS"
|
||||
"github.com/taosdata/driver-go/v3/ws/schemaless"
|
||||
)
|
||||
|
||||
func main() {
|
||||
db, err := sql.Open("taosWS", "root:taosdata@ws(localhost:6041)/")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer db.Close()
|
||||
_, err = db.Exec("create database if not exists schemaless_ws")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
s, err := schemaless.NewSchemaless(schemaless.NewConfig("ws://localhost:6041/rest/schemaless", 1,
|
||||
schemaless.SetDb("schemaless_ws"),
|
||||
schemaless.SetReadTimeout(10*time.Second),
|
||||
schemaless.SetWriteTimeout(10*time.Second),
|
||||
schemaless.SetUser("root"),
|
||||
schemaless.SetPassword("taosdata"),
|
||||
schemaless.SetErrorHandler(func(err error) {
|
||||
log.Fatal(err)
|
||||
}),
|
||||
))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
influxdbData := "st,t1=3i64,t2=4f64,t3=\"t3\" c1=3i64,c3=L\"passit\",c2=false,c4=4f64 1626006833639000000"
|
||||
telnetData := "stb0_0 1626006833 4 host=host0 interface=eth0"
|
||||
jsonData := "{\"metric\": \"meter_current\",\"timestamp\": 1626846400,\"value\": 10.3, \"tags\": {\"groupid\": 2, \"location\": \"California.SanFrancisco\", \"id\": \"d1001\"}}"
|
||||
|
||||
err = s.Insert(influxdbData, schemaless.InfluxDBLineProtocol, "ns", 0, common.GetReqID())
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = s.Insert(telnetData, schemaless.OpenTSDBTelnetLineProtocol, "ms", 0, common.GetReqID())
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = s.Insert(jsonData, schemaless.OpenTSDBJsonFormatProtocol, "ms", 0, common.GetReqID())
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
{{#include docs/examples/go/demo/smlws/main.go}}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
|
@ -777,89 +317,31 @@ TDengine Go 连接器支持订阅功能,应用 API 如下:
|
|||
#### 创建 Topic
|
||||
|
||||
```go
|
||||
db, err := af.Open("", "root", "taosdata", "", 0)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer db.Close()
|
||||
_, err = db.Exec("create database if not exists example_tmq WAL_RETENTION_PERIOD 86400")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
_, err = db.Exec("create topic if not exists example_tmq_topic as DATABASE example_tmq")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
{{#include docs/examples/go/demo/consumer/main.go:create_topic}}
|
||||
```
|
||||
|
||||
#### 创建 Consumer
|
||||
|
||||
```go
|
||||
consumer, err := tmq.NewConsumer(&tmqcommon.ConfigMap{
|
||||
"group.id": "test",
|
||||
"auto.offset.reset": "latest",
|
||||
"td.connect.ip": "127.0.0.1",
|
||||
"td.connect.user": "root",
|
||||
"td.connect.pass": "taosdata",
|
||||
"td.connect.port": "6030",
|
||||
"client.id": "test_tmq_client",
|
||||
"enable.auto.commit": "false",
|
||||
"msg.with.table.name": "true",
|
||||
})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
{{#include docs/examples/go/demo/consumer/main.go:create_consumer}}
|
||||
```
|
||||
|
||||
#### 订阅消费数据
|
||||
|
||||
```go
|
||||
err = consumer.Subscribe("example_tmq_topic", nil)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for i := 0; i < 5; i++ {
|
||||
ev := consumer.Poll(500)
|
||||
if ev != nil {
|
||||
switch e := ev.(type) {
|
||||
case *tmqcommon.DataMessage:
|
||||
fmt.Printf("get message:%v\n", e)
|
||||
case tmqcommon.Error:
|
||||
fmt.Fprintf(os.Stderr, "%% Error: %v: %v\n", e.Code(), e)
|
||||
panic(e)
|
||||
}
|
||||
consumer.Commit()
|
||||
}
|
||||
}
|
||||
{{#include docs/examples/go/demo/consumer/main.go:poll_data}}
|
||||
```
|
||||
|
||||
#### 指定订阅 Offset
|
||||
|
||||
```go
|
||||
partitions, err := consumer.Assignment()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for i := 0; i < len(partitions); i++ {
|
||||
fmt.Println(partitions[i])
|
||||
err = consumer.Seek(tmqcommon.TopicPartition{
|
||||
Topic: partitions[i].Topic,
|
||||
Partition: partitions[i].Partition,
|
||||
Offset: 0,
|
||||
}, 0)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
{{#include docs/examples/go/demo/consumer/main.go:consumer_seek}}
|
||||
```
|
||||
|
||||
#### 关闭订阅
|
||||
|
||||
```go
|
||||
err = consumer.Close()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
{{#include docs/examples/go/demo/consumer/main.go:consumer_close}}
|
||||
```
|
||||
|
||||
#### 完整示例
|
||||
|
@ -868,232 +350,14 @@ TDengine Go 连接器支持订阅功能,应用 API 如下:
|
|||
<TabItem value="native" label="原生连接">
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/taosdata/driver-go/v3/af"
|
||||
"github.com/taosdata/driver-go/v3/af/tmq"
|
||||
tmqcommon "github.com/taosdata/driver-go/v3/common/tmq"
|
||||
)
|
||||
|
||||
func main() {
|
||||
db, err := af.Open("", "root", "taosdata", "", 0)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer db.Close()
|
||||
_, err = db.Exec("create database if not exists example_tmq WAL_RETENTION_PERIOD 86400")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
_, err = db.Exec("create topic if not exists example_tmq_topic as DATABASE example_tmq")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
consumer, err := tmq.NewConsumer(&tmqcommon.ConfigMap{
|
||||
"group.id": "test",
|
||||
"auto.offset.reset": "latest",
|
||||
"td.connect.ip": "127.0.0.1",
|
||||
"td.connect.user": "root",
|
||||
"td.connect.pass": "taosdata",
|
||||
"td.connect.port": "6030",
|
||||
"client.id": "test_tmq_client",
|
||||
"enable.auto.commit": "false",
|
||||
"msg.with.table.name": "true",
|
||||
})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = consumer.Subscribe("example_tmq_topic", nil)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
_, err = db.Exec("create table example_tmq.t1 (ts timestamp,v int)")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
go func() {
|
||||
for {
|
||||
_, err = db.Exec("insert into example_tmq.t1 values(now,1)")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
time.Sleep(time.Millisecond * 100)
|
||||
}
|
||||
}()
|
||||
|
||||
for i := 0; i < 5; i++ {
|
||||
ev := consumer.Poll(500)
|
||||
if ev != nil {
|
||||
switch e := ev.(type) {
|
||||
case *tmqcommon.DataMessage:
|
||||
fmt.Printf("get message:%v\n", e)
|
||||
case tmqcommon.Error:
|
||||
fmt.Fprintf(os.Stderr, "%% Error: %v: %v\n", e.Code(), e)
|
||||
panic(e)
|
||||
}
|
||||
consumer.Commit()
|
||||
}
|
||||
}
|
||||
partitions, err := consumer.Assignment()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for i := 0; i < len(partitions); i++ {
|
||||
fmt.Println(partitions[i])
|
||||
err = consumer.Seek(tmqcommon.TopicPartition{
|
||||
Topic: partitions[i].Topic,
|
||||
Partition: partitions[i].Partition,
|
||||
Offset: 0,
|
||||
}, 0)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
partitions, err = consumer.Assignment()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for i := 0; i < len(partitions); i++ {
|
||||
fmt.Println(partitions[i])
|
||||
}
|
||||
|
||||
err = consumer.Close()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
{{#include docs/examples/go/demo/consumer/main.go}}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="WebSocket" label="WebSocket 连接">
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/taosdata/driver-go/v3/common"
|
||||
tmqcommon "github.com/taosdata/driver-go/v3/common/tmq"
|
||||
_ "github.com/taosdata/driver-go/v3/taosRestful"
|
||||
"github.com/taosdata/driver-go/v3/ws/tmq"
|
||||
)
|
||||
|
||||
func main() {
|
||||
db, err := sql.Open("taosRestful", "root:taosdata@http(localhost:6041)/")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer db.Close()
|
||||
prepareEnv(db)
|
||||
consumer, err := tmq.NewConsumer(&tmqcommon.ConfigMap{
|
||||
"ws.url": "ws://127.0.0.1:6041/rest/tmq",
|
||||
"ws.message.channelLen": uint(0),
|
||||
"ws.message.timeout": common.DefaultMessageTimeout,
|
||||
"ws.message.writeWait": common.DefaultWriteWait,
|
||||
"td.connect.user": "root",
|
||||
"td.connect.pass": "taosdata",
|
||||
"group.id": "example",
|
||||
"client.id": "example_consumer",
|
||||
"auto.offset.reset": "latest",
|
||||
})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = consumer.Subscribe("example_ws_tmq_topic", nil)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
_, err = db.Exec("create table example_ws_tmq.t_all(ts timestamp," +
|
||||
"c1 bool," +
|
||||
"c2 tinyint," +
|
||||
"c3 smallint," +
|
||||
"c4 int," +
|
||||
"c5 bigint," +
|
||||
"c6 tinyint unsigned," +
|
||||
"c7 smallint unsigned," +
|
||||
"c8 int unsigned," +
|
||||
"c9 bigint unsigned," +
|
||||
"c10 float," +
|
||||
"c11 double," +
|
||||
"c12 binary(20)," +
|
||||
"c13 nchar(20)" +
|
||||
")")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
go func() {
|
||||
for {
|
||||
_, err = db.Exec("insert into example_ws_tmq.t_all values(now,true,2,3,4,5,6,7,8,9,10.123,11.123,'binary','nchar')")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
time.Sleep(time.Millisecond * 100)
|
||||
}
|
||||
|
||||
}()
|
||||
for i := 0; i < 5; i++ {
|
||||
ev := consumer.Poll(500)
|
||||
if ev != nil {
|
||||
switch e := ev.(type) {
|
||||
case *tmqcommon.DataMessage:
|
||||
fmt.Printf("get message:%v\n", e)
|
||||
case tmqcommon.Error:
|
||||
fmt.Printf("%% Error: %v: %v\n", e.Code(), e)
|
||||
panic(e)
|
||||
}
|
||||
consumer.Commit()
|
||||
}
|
||||
}
|
||||
partitions, err := consumer.Assignment()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for i := 0; i < len(partitions); i++ {
|
||||
fmt.Println(partitions[i])
|
||||
err = consumer.Seek(tmqcommon.TopicPartition{
|
||||
Topic: partitions[i].Topic,
|
||||
Partition: partitions[i].Partition,
|
||||
Offset: 0,
|
||||
}, 0)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
partitions, err = consumer.Assignment()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for i := 0; i < len(partitions); i++ {
|
||||
fmt.Println(partitions[i])
|
||||
}
|
||||
|
||||
err = consumer.Close()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func prepareEnv(db *sql.DB) {
|
||||
_, err := db.Exec("create database example_ws_tmq WAL_RETENTION_PERIOD 86400")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
_, err = db.Exec("create topic example_ws_tmq_topic as database example_ws_tmq")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
{{#include docs/examples/go/demo/consumerws/main.go}}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
|
|
|
@ -12,15 +12,24 @@ import RustInsert from "../07-develop/03-insert-data/_rust_sql.mdx"
|
|||
import RustBind from "../07-develop/03-insert-data/_rust_stmt.mdx"
|
||||
import RustSml from "../07-develop/03-insert-data/_rust_schemaless.mdx"
|
||||
import RustQuery from "../07-develop/04-query-data/_rust.mdx"
|
||||
import RequestId from "./_request_id.mdx";
|
||||
|
||||
[](https://crates.io/crates/taos)  [](https://docs.rs/taos)
|
||||
|
||||
`taos` 是 TDengine 的官方 Rust 语言连接器。Rust 开发人员可以通过它开发存取 TDengine 数据库的应用软件。
|
||||
|
||||
`taos` 提供两种建立连接的方式。一种是**原生连接**,它通过 TDengine 客户端驱动程序(taosc)连接 TDengine 运行实例。另外一种是 **Websocket 连接**,它通过 taosAdapter 的 Websocket 接口连接 TDengine 运行实例。你可以通过不同的 “特性(即 Cargo 关键字 `features`)” 来指定使用哪种连接器(默认同时支持)。Websocket 连接支持任何平台,原生连接支持所有 TDengine 客户端能运行的平台。
|
||||
|
||||
该 Rust 连接器的源码托管在 [GitHub](https://github.com/taosdata/taos-connector-rust)。
|
||||
|
||||
## 连接方式
|
||||
|
||||
`taos` 提供两种建立连接的方式。一般我们推荐使用 **Websocket 连接**。
|
||||
- **原生连接**,它通过 TDengine 客户端驱动程序(taosc)连接 TDengine 运行实例。
|
||||
- **Websocket 连接**,它通过 taosAdapter 的 Websocket 接口连接 TDengine 运行实例。
|
||||
|
||||
你可以通过不同的 “特性(即 Cargo 关键字 `features`)” 来指定使用哪种连接器(默认同时支持)。
|
||||
|
||||
连接方式的详细介绍请参考:[连接器建立连接的方式](../../develop/connect/#连接器建立连接的方式)
|
||||
|
||||
## 支持的平台
|
||||
|
||||
原生连接支持的平台和 TDengine 客户端驱动支持的平台一致。
|
||||
|
@ -30,8 +39,11 @@ Websocket 连接支持所有能运行 Rust 的平台。
|
|||
|
||||
| Rust 连接器版本 | TDengine 版本 | 主要功能 |
|
||||
| :----------------: | :--------------: | :--------------------------------------------------: |
|
||||
| v0.9.2 | 3.0.7.0 or later | STMT:ws 下获取 tag_fields、col_fields。 |
|
||||
| v0.8.12 | 3.0.5.0 | 消息订阅:获取消费进度及按照指定进度开始消费。 |
|
||||
| v0.12.0 | 3.2.3.0 or later | WS 支持压缩。 |
|
||||
| v0.11.0 | 3.2.0.0 | TMQ 功能优化。 |
|
||||
| v0.10.0 | 3.1.0.0 | WS endpoint 变更。 |
|
||||
| v0.9.2 | 3.0.7.0 | STMT:ws 下获取 tag_fields、col_fields。 |
|
||||
| v0.8.12 | 3.0.5.0 | 消息订阅:获取消费进度及按照指定进度开始消费。 |
|
||||
| v0.8.0 | 3.0.4.0 | 支持无模式写入。 |
|
||||
| v0.7.6 | 3.0.3.0 | 支持在请求中使用 req_id。 |
|
||||
| v0.6.0 | 3.0.0.0 | 基础功能。 |
|
||||
|
@ -68,7 +80,7 @@ TDengine 目前支持时间戳、数字、字符、布尔类型,与 Rust 对
|
|||
| SMALLINT | i16 |
|
||||
| TINYINT | i8 |
|
||||
| BOOL | bool |
|
||||
| BINARY | Vec<u8\> |
|
||||
| BINARY | Vec\<u8> |
|
||||
| NCHAR | String |
|
||||
| JSON | serde_json::Value |
|
||||
|
||||
|
@ -274,52 +286,29 @@ async fn demo(taos: &Taos, db: &str) -> Result<(), Error> {
|
|||
### 创建数据库和表
|
||||
|
||||
```rust
|
||||
use taos::*;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> anyhow::Result<()> {
|
||||
let dsn = "taos://localhost:6030";
|
||||
let builder = TaosBuilder::from_dsn(dsn)?;
|
||||
|
||||
let taos = builder.build()?;
|
||||
|
||||
let db = "query";
|
||||
|
||||
// create database
|
||||
taos.exec_many([
|
||||
format!("DROP DATABASE IF EXISTS `{db}`"),
|
||||
format!("CREATE DATABASE `{db}`"),
|
||||
format!("USE `{db}`"),
|
||||
])
|
||||
.await?;
|
||||
|
||||
// create table
|
||||
taos.exec_many([
|
||||
// create super table
|
||||
"CREATE TABLE `meters` (`ts` TIMESTAMP, `current` FLOAT, `voltage` INT, `phase` FLOAT) \
|
||||
TAGS (`groupid` INT, `location` BINARY(16))",
|
||||
// create child table
|
||||
"CREATE TABLE `d0` USING `meters` TAGS(0, 'Los Angles')",
|
||||
]).await?;
|
||||
}
|
||||
{{#include docs/examples/rust/nativeexample/examples/query.rs:create_db_and_table}}
|
||||
```
|
||||
|
||||
> **注意**:如果不使用 `use db` 指定数据库,则后续对表的操作都需要增加数据库名称作为前缀,如 db.tb。
|
||||
|
||||
### 插入数据
|
||||
|
||||
<RustInsert />
|
||||
```rust
|
||||
{{#include docs/examples/rust/nativeexample/examples/query.rs:insert_data}}
|
||||
```
|
||||
|
||||
### 查询数据
|
||||
|
||||
<RustQuery />
|
||||
```rust
|
||||
{{#include docs/examples/rust/nativeexample/examples/query.rs:query_data}}
|
||||
```
|
||||
|
||||
### 执行带有 req_id 的 SQL
|
||||
|
||||
此 req_id 可用于请求链路追踪。
|
||||
<RequestId />
|
||||
|
||||
```rust
|
||||
let rs = taos.query_with_req_id("select * from stable where tag1 is null", 1)?;
|
||||
{{#include docs/examples/rust/nativeexample/examples/query.rs:query_with_req_id}}
|
||||
```
|
||||
|
||||
### 通过参数绑定写入数据
|
||||
|
@ -328,13 +317,17 @@ TDengine 的 Rust 连接器实现了参数绑定方式对数据写入(INSERT
|
|||
|
||||
参数绑定接口详见[API参考](#stmt-api)
|
||||
|
||||
<RustBind />
|
||||
```rust
|
||||
{{#include docs/examples/rust/nativeexample/examples/stmt.rs}}
|
||||
```
|
||||
|
||||
### 无模式写入
|
||||
|
||||
TDengine 支持无模式写入功能。无模式写入兼容 InfluxDB 的 行协议(Line Protocol)、OpenTSDB 的 telnet 行协议和 OpenTSDB 的 JSON 格式协议。详情请参见[无模式写入](../../reference/schemaless/)。
|
||||
|
||||
<RustSml />
|
||||
```rust
|
||||
{{#include docs/examples/rust/nativeexample/examples/schemaless.rs}}
|
||||
```
|
||||
|
||||
### 执行带有 req_id 的无模式写入
|
||||
|
||||
|
@ -357,25 +350,15 @@ TDengine 通过消息队列 [TMQ](../../taos-sql/tmq/) 启动一个订阅。
|
|||
#### 创建 Topic
|
||||
|
||||
```rust
|
||||
taos.exec_many([
|
||||
// create topic for subscription
|
||||
format!("CREATE TOPIC tmq_meters with META AS DATABASE {db}")
|
||||
])
|
||||
.await?;
|
||||
{{#include docs/examples/rust/nativeexample/examples/tmq.rs:create_topic}}
|
||||
```
|
||||
|
||||
#### 创建 Consumer
|
||||
|
||||
从 DSN 开始,构建一个 TMQ 连接器。
|
||||
|
||||
```rust
|
||||
let tmq = TmqBuilder::from_dsn("taos://localhost:6030/?group.id=test")?;
|
||||
```
|
||||
|
||||
创建消费者:
|
||||
|
||||
```rust
|
||||
let mut consumer = tmq.build()?;
|
||||
{{#include docs/examples/rust/nativeexample/examples/tmq.rs:create_consumer}}
|
||||
```
|
||||
|
||||
#### 订阅消费数据
|
||||
|
@ -383,40 +366,13 @@ let mut consumer = tmq.build()?;
|
|||
消费者可订阅一个或多个 `TOPIC`。
|
||||
|
||||
```rust
|
||||
consumer.subscribe(["tmq_meters"]).await?;
|
||||
{{#include docs/examples/rust/nativeexample/examples/tmq.rs:subscribe}}
|
||||
```
|
||||
|
||||
TMQ 消息队列是一个 [futures::Stream](https://docs.rs/futures/latest/futures/stream/index.html) 类型,可以使用相应 API 对每个消息进行消费,并通过 `.commit` 进行已消费标记。
|
||||
|
||||
```rust
|
||||
{
|
||||
let mut stream = consumer.stream();
|
||||
|
||||
while let Some((offset, message)) = stream.try_next().await? {
|
||||
// get information from offset
|
||||
|
||||
// the topic
|
||||
let topic = offset.topic();
|
||||
// the vgroup id, like partition id in kafka.
|
||||
let vgroup_id = offset.vgroup_id();
|
||||
println!("* in vgroup id {vgroup_id} of topic {topic}\n");
|
||||
|
||||
if let Some(data) = message.into_data() {
|
||||
while let Some(block) = data.fetch_raw_block().await? {
|
||||
// one block for one table, get table name if needed
|
||||
let name = block.table_name();
|
||||
let records: Vec<Record> = block.deserialize().try_collect()?;
|
||||
println!(
|
||||
"** table: {}, got {} records: {:#?}\n",
|
||||
name.unwrap(),
|
||||
records.len(),
|
||||
records
|
||||
);
|
||||
}
|
||||
}
|
||||
consumer.commit(offset).await?;
|
||||
}
|
||||
}
|
||||
{{#include docs/examples/rust/nativeexample/examples/tmq.rs:consume}}
|
||||
```
|
||||
|
||||
获取消费进度:
|
||||
|
@ -424,7 +380,7 @@ TMQ 消息队列是一个 [futures::Stream](https://docs.rs/futures/latest/futur
|
|||
版本要求 connector-rust >= v0.8.8, TDengine >= 3.0.5.0
|
||||
|
||||
```rust
|
||||
let assignments = consumer.assignments().await.unwrap();
|
||||
{{#include docs/examples/rust/nativeexample/examples/tmq.rs:assignments}}
|
||||
```
|
||||
|
||||
#### 指定订阅 Offset
|
||||
|
@ -434,13 +390,13 @@ let assignments = consumer.assignments().await.unwrap();
|
|||
版本要求 connector-rust >= v0.8.8, TDengine >= 3.0.5.0
|
||||
|
||||
```rust
|
||||
consumer.offset_seek(topic, vgroup_id, offset).await;
|
||||
{{#include docs/examples/rust/nativeexample/examples/tmq.rs:seek_offset}}
|
||||
```
|
||||
|
||||
#### 关闭订阅
|
||||
|
||||
```rust
|
||||
consumer.unsubscribe().await;
|
||||
{{#include docs/examples/rust/nativeexample/examples/tmq.rs:unsubscribe}}
|
||||
```
|
||||
|
||||
对于 TMQ DSN, 有以下配置项可以进行设置,需要注意的是,`group.id` 是必须的。
|
||||
|
@ -453,7 +409,7 @@ consumer.unsubscribe().await;
|
|||
|
||||
#### 完整示例
|
||||
|
||||
完整订阅示例参见 [GitHub 示例文件](https://github.com/taosdata/TDengine/blob/3.0/docs/examples/rust/nativeexample/examples/subscribe_demo.rs).
|
||||
完整订阅示例参见 [GitHub 示例文件](https://github.com/taosdata/TDengine/blob/3.0/docs/examples/rust/nativeexample/examples/tmq.rs).
|
||||
|
||||
### 与连接池使用
|
||||
|
||||
|
@ -655,7 +611,7 @@ stmt.execute()?;
|
|||
一个可运行的示例请见 [GitHub 上的示例](https://github.com/taosdata/taos-connector-rust/blob/main/examples/bind.rs)。
|
||||
|
||||
|
||||
其他相关结构体 API 使用说明请移步 Rust 文档托管网页:<https://docs.rs/taos>。
|
||||
其他相关结构体 API 使用说明请移步 Rust 文档托管网页:\<https://docs.rs/taos>。
|
||||
|
||||
[taos]: https://github.com/taosdata/rust-connector-taos
|
||||
[deadpool]: https://crates.io/crates/deadpool
|
||||
|
|
|
@ -7,16 +7,24 @@ description: "taospy 是 TDengine 的官方 Python 连接器。taospy 提供了
|
|||
|
||||
import Tabs from "@theme/Tabs";
|
||||
import TabItem from "@theme/TabItem";
|
||||
import RequestId from "./_request_id.mdx";
|
||||
|
||||
`taospy` 是 TDengine 的官方 Python 连接器。`taospy` 提供了丰富的 API, 使得 Python 应用可以很方便地使用 TDengine。`taospy` 对 TDengine 的[原生接口](../cpp)和 [REST 接口](../rest-api)都进行了封装, 分别对应 `taospy` 包的 `taos` 模块 和 `taosrest` 模块。
|
||||
除了对原生接口和 REST 接口的封装,`taospy` 还提供了符合 [Python 数据访问规范(PEP 249)](https://peps.python.org/pep-0249/) 的编程接口。这使得 `taospy` 和很多第三方工具集成变得简单,比如 [SQLAlchemy](https://www.sqlalchemy.org/) 和 [pandas](https://pandas.pydata.org/)。
|
||||
|
||||
`taos-ws-py` 是使用 WebSocket 方式连接 TDengine 的 Python 连接器包。可以选装。
|
||||
|
||||
使用客户端驱动提供的原生接口直接与服务端建立的连接的方式下文中称为“原生连接”;使用 taosAdapter 提供的 REST 接口或 WebSocket 接口与服务端建立的连接的方式下文中称为“REST 连接”或“WebSocket 连接”。
|
||||
`taospy` 是 TDengine 的官方 Python 连接器。`taospy` 提供了丰富的 API, 使得 Python 应用可以很方便地使用 TDengine。
|
||||
|
||||
Python 连接器的源码托管在 [GitHub](https://github.com/taosdata/taos-connector-python)。
|
||||
|
||||
## 连接方式
|
||||
`taospy`主要提供三种形式的连接器。一般我们推荐使用 **Websocket 连接**。
|
||||
- **原生连接**,对应 `taospy` 包的 `taos` 模块。通过 TDengine 客户端驱动程序(taosc)原生连接 TDengine 实例,支持数据写入、查询、数据订阅、schemaless 接口和参数绑定接口等功能。
|
||||
- **REST 连接**,对应 `taospy` 包的 `taosrest` 模块。通过 taosAdapter 提供的 HTTP 接口连接 TDengine 实例,不支持 schemaless 和数据订阅等特性。
|
||||
- **Websocket 连接**,对应 `taos-ws-py` 包,可以选装。通过 taosAdapter 提供的 Websocket 接口连接 TDengine 实例,WebSocket 连接实现的功能集合和原生连接有少量不同。
|
||||
|
||||
连接方式的详细介绍请参考:[连接器建立连接的方式](../../develop/connect/#连接器建立连接的方式)
|
||||
|
||||
除了对原生接口和 REST 接口的封装,`taospy` 还提供了符合 [Python 数据访问规范(PEP 249)](https://peps.python.org/pep-0249/) 的编程接口。这使得 `taospy` 和很多第三方工具集成变得简单,比如 [SQLAlchemy](https://www.sqlalchemy.org/) 和 [pandas](https://pandas.pydata.org/)。
|
||||
|
||||
使用客户端驱动提供的原生接口直接与服务端建立的连接的方式下文中称为“原生连接”;使用 taosAdapter 提供的 REST 接口或 WebSocket 接口与服务端建立的连接的方式下文中称为“REST 连接”或“WebSocket 连接”。
|
||||
|
||||
## 支持的平台
|
||||
|
||||
- 原生连接[支持的平台](../#支持的平台)和 TDengine 客户端支持的平台一致。
|
||||
|
@ -317,7 +325,7 @@ Transfer-Encoding: chunked
|
|||
|
||||
`connect()` 函数的所有参数都是可选的关键字参数。下面是连接参数的具体说明:
|
||||
|
||||
- `url`: taosAdapter REST 服务的 URL。默认是 <http://localhost:6041>。
|
||||
- `url`: taosAdapter REST 服务的 URL。默认是 \<http://localhost:6041>。
|
||||
- `user`: TDengine 用户名。默认是 root。
|
||||
- `password`: TDengine 用户密码。默认是 taosdata。
|
||||
- `timeout`: HTTP 请求超时时间。单位为秒。默认为 `socket._GLOBAL_DEFAULT_TIMEOUT`。 一般无需配置。
|
||||
|
@ -350,13 +358,7 @@ Transfer-Encoding: chunked
|
|||
<TabItem value="native" label="原生连接">
|
||||
|
||||
```python
|
||||
conn = taos.connect()
|
||||
# Execute a sql, ignore the result set, just get affected rows. It's useful for DDL and DML statement.
|
||||
conn.execute("DROP DATABASE IF EXISTS test")
|
||||
conn.execute("CREATE DATABASE test")
|
||||
# change database. same as execute "USE db"
|
||||
conn.select_db("test")
|
||||
conn.execute("CREATE STABLE weather(ts TIMESTAMP, temperature FLOAT) TAGS (location INT)")
|
||||
{{#include docs/examples/python/create_db_native.py}}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
|
@ -364,12 +366,7 @@ conn.execute("CREATE STABLE weather(ts TIMESTAMP, temperature FLOAT) TAGS (locat
|
|||
<TabItem value="rest" label="REST 连接">
|
||||
|
||||
```python
|
||||
conn = taosrest.connect(url="http://localhost:6041")
|
||||
# Execute a sql, ignore the result set, just get affected rows. It's useful for DDL and DML statement.
|
||||
conn.execute("DROP DATABASE IF EXISTS test")
|
||||
conn.execute("CREATE DATABASE test")
|
||||
conn.execute("USE test")
|
||||
conn.execute("CREATE STABLE weather(ts TIMESTAMP, temperature FLOAT) TAGS (location INT)")
|
||||
{{#include docs/examples/python/create_db_rest.py}}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
|
@ -377,12 +374,7 @@ conn.execute("CREATE STABLE weather(ts TIMESTAMP, temperature FLOAT) TAGS (locat
|
|||
<TabItem value="websocket" label="WebSocket 连接">
|
||||
|
||||
```python
|
||||
conn = taosws.connect("taosws://localhost:6041")
|
||||
# Execute a sql, ignore the result set, just get affected rows. It's useful for DDL and DML statement.
|
||||
conn.execute("DROP DATABASE IF EXISTS test")
|
||||
conn.execute("CREATE DATABASE test")
|
||||
conn.execute("USE test")
|
||||
conn.execute("CREATE STABLE weather(ts TIMESTAMP, temperature FLOAT) TAGS (location INT)")
|
||||
{{#include docs/examples/python/create_db_ws.py}}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
|
@ -390,101 +382,35 @@ conn.execute("CREATE STABLE weather(ts TIMESTAMP, temperature FLOAT) TAGS (locat
|
|||
|
||||
### 插入数据
|
||||
|
||||
```python
|
||||
conn.execute("INSERT INTO t1 USING weather TAGS(1) VALUES (now, 23.5) (now+1m, 23.5) (now+2m, 24.4)")
|
||||
```
|
||||
|
||||
:::
|
||||
now 为系统内部函数,默认为客户端所在计算机当前时间。 now + 1s 代表客户端当前时间往后加 1 秒,数字后面代表时间单位:a(毫秒),s(秒),m(分),h(小时),d(天),w(周),n(月),y(年)。
|
||||
:::
|
||||
|
||||
### 基本使用
|
||||
|
||||
<Tabs defaultValue="rest">
|
||||
<TabItem value="native" label="原生连接">
|
||||
|
||||
##### TaosConnection 类的使用
|
||||
|
||||
`TaosConnection` 类既包含对 PEP249 Connection 接口的实现(如:`cursor`方法和 `close` 方法),也包含很多扩展功能(如: `execute`、 `query`、`schemaless_insert` 和 `subscribe` 方法。
|
||||
|
||||
```python title="execute 方法"
|
||||
{{#include docs/examples/python/connection_usage_native_reference.py:insert}}
|
||||
```python
|
||||
{{#include docs/examples/python/insert_native.py:insert}}
|
||||
```
|
||||
|
||||
```python title="query 方法"
|
||||
{{#include docs/examples/python/connection_usage_native_reference.py:query}}
|
||||
```
|
||||
|
||||
:::tip
|
||||
查询结果只能获取一次。比如上面的示例中 `fetch_all()` 和 `fetch_all_into_dict()` 只能用一个。重复获取得到的结果为空列表。
|
||||
:::
|
||||
|
||||
##### TaosResult 类的使用
|
||||
|
||||
上面 `TaosConnection` 类的使用示例中,我们已经展示了两种获取查询结果的方法: `fetch_all()` 和 `fetch_all_into_dict()`。除此之外 `TaosResult` 还提供了按行迭代(`rows_iter`)或按数据块迭代(`blocks_iter`)结果集的方法。在查询数据量较大的场景,使用这两个方法会更高效。
|
||||
|
||||
```python title="blocks_iter 方法"
|
||||
{{#include docs/examples/python/result_set_examples.py}}
|
||||
```
|
||||
##### TaosCursor 类的使用
|
||||
|
||||
`TaosConnection` 类和 `TaosResult` 类已经实现了原生接口的所有功能。如果你对 PEP249 规范中的接口比较熟悉也可以使用 `TaosCursor` 类提供的方法。
|
||||
|
||||
```python title="TaosCursor 的使用"
|
||||
{{#include docs/examples/python/cursor_usage_native_reference.py}}
|
||||
```
|
||||
|
||||
:::note
|
||||
TaosCursor 类使用原生连接进行写入、查询操作。在客户端多线程的场景下,这个游标实例必须保持线程独享,不能跨线程共享使用,否则会导致返回结果出现错误。
|
||||
|
||||
TaosCursor 的最佳实践是,查询开始时创建 cursor,用完之后就关闭,请避免复用同一个 cursor 多次执行。
|
||||
:::
|
||||
|
||||
</TabItem>
|
||||
|
||||
<TabItem value="rest" label="REST 连接">
|
||||
|
||||
##### RestClient 类的使用
|
||||
|
||||
`RestClient` 类是对于 [REST API](../rest-api) 的直接封装。它只包含一个 `sql()` 方法用于执行任意 SQL 语句, 并返回执行结果。
|
||||
|
||||
```python title="RestClient 的使用"
|
||||
{{#include docs/examples/python/rest_client_example.py}}
|
||||
```python
|
||||
{{#include docs/examples/python/insert_rest.py:insert}}
|
||||
```
|
||||
|
||||
对于 `sql()` 方法更详细的介绍, 请参考 [RestClient](https://docs.taosdata.com/api/taospy/taosrest/restclient.html)。
|
||||
|
||||
##### TaosRestCursor 类的使用
|
||||
|
||||
`TaosRestCursor` 类是对 PEP249 Cursor 接口的实现。
|
||||
|
||||
```python title="TaosRestCursor 的使用"
|
||||
{{#include docs/examples/python/connect_rest_examples.py:basic}}
|
||||
```
|
||||
- `cursor.execute` : 用来执行任意 SQL 语句。
|
||||
- `cursor.rowcount`: 对于写入操作返回写入成功记录数。对于查询操作,返回结果集行数。
|
||||
- `cursor.description` : 返回字段的描述信息。关于描述信息的具体格式请参考[TaosRestCursor](https://docs.taosdata.com/api/taospy/taosrest/cursor.html)。
|
||||
|
||||
:::note
|
||||
TaosRestCursor 的最佳实践是,查询开始时创建 cursor,用完之后就关闭,请避免复用同一个 cursor 多次执行。
|
||||
:::
|
||||
|
||||
</TabItem>
|
||||
|
||||
<TabItem value="websocket" label="WebSocket 连接">
|
||||
|
||||
##### Connection 类的使用
|
||||
|
||||
`Connection` 类既包含对 PEP249 Connection 接口的实现(如:cursor方法和 close 方法),也包含很多扩展功能(如: execute、 query、schemaless_insert 和 subscribe 方法。
|
||||
|
||||
```python
|
||||
{{#include docs/examples/python/connect_websocket_examples.py:basic}}
|
||||
{{#include docs/examples/python/insert_ws.py:insert}}
|
||||
```
|
||||
|
||||
- `conn.execute`: 用来执行任意 SQL 语句,返回影响的行数
|
||||
- `conn.query`: 用来执行查询 SQL 语句,返回查询结果
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
> NOW 为系统内部函数,默认为客户端所在计算机当前时间。
|
||||
> `NOW + 1s` 代表客户端当前时间往后加 1 秒,数字后面代表时间单位:a(毫秒),s(秒),m(分),h(小时),d(天),w(周),n(月),y(年)。
|
||||
|
||||
### 查询数据
|
||||
|
||||
<Tabs defaultValue="rest">
|
||||
|
@ -493,7 +419,7 @@ TaosRestCursor 的最佳实践是,查询开始时创建 cursor,用完之后
|
|||
`TaosConnection` 类的 `query` 方法可以用来查询数据,返回 `TaosResult` 类型的结果数据。
|
||||
|
||||
```python
|
||||
{{#include docs/examples/python/connection_usage_native_reference.py:query}}
|
||||
{{#include docs/examples/python/insert_native.py:query}}
|
||||
```
|
||||
|
||||
:::tip
|
||||
|
@ -507,7 +433,7 @@ TaosRestCursor 的最佳实践是,查询开始时创建 cursor,用完之后
|
|||
RestClient 类是对于 REST API 的直接封装。它只包含一个 sql() 方法用于执行任意 SQL 语句, 并返回执行结果。
|
||||
|
||||
```python
|
||||
{{#include docs/examples/python/rest_client_example.py}}
|
||||
{{#include docs/examples/python/insert_rest.py:query}}
|
||||
```
|
||||
|
||||
对于 `sql()` 方法更详细的介绍, 请参考 [RestClient](https://docs.taosdata.com/api/taospy/taosrest/restclient.html)。
|
||||
|
@ -519,7 +445,7 @@ RestClient 类是对于 REST API 的直接封装。它只包含一个 sql() 方
|
|||
`TaosConnection` 类的 `query` 方法可以用来查询数据,返回 `TaosResult` 类型的结果数据。
|
||||
|
||||
```python
|
||||
{{#include docs/examples/python/connect_websocket_examples.py:basic}}
|
||||
{{#include docs/examples/python/insert_ws.py:query}}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
|
@ -527,36 +453,15 @@ RestClient 类是对于 REST API 的直接封装。它只包含一个 sql() 方
|
|||
|
||||
### 执行带有 reqId 的 SQL
|
||||
|
||||
使用可选的 req_id 参数,指定请求 id,可以用于 tracing
|
||||
<RequestId />
|
||||
|
||||
<Tabs defaultValue="rest">
|
||||
<TabItem value="native" label="原生连接">
|
||||
|
||||
##### TaosConnection 类的使用
|
||||
|
||||
类似上文介绍的使用方法,增加 `req_id` 参数。
|
||||
|
||||
```python title="execute 方法"
|
||||
{{#include docs/examples/python/connection_usage_native_reference_with_req_id.py:insert}}
|
||||
```
|
||||
|
||||
```python title="query 方法"
|
||||
{{#include docs/examples/python/connection_usage_native_reference_with_req_id.py:query}}
|
||||
```
|
||||
|
||||
##### TaosResult 类的使用
|
||||
|
||||
类似上文介绍的使用方法,增加 `req_id` 参数。
|
||||
|
||||
```python title="blocks_iter 方法"
|
||||
{{#include docs/examples/python/result_set_with_req_id_examples.py}}
|
||||
```
|
||||
##### TaosCursor 类的使用
|
||||
|
||||
`TaosConnection` 类和 `TaosResult` 类已经实现了原生接口的所有功能。如果你对 PEP249 规范中的接口比较熟悉也可以使用 `TaosCursor` 类提供的方法。
|
||||
|
||||
```python title="TaosCursor 的使用"
|
||||
{{#include docs/examples/python/cursor_usage_native_reference_with_req_id.py}}
|
||||
```python
|
||||
{{#include docs/examples/python/insert_native.py:req_id}}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
|
@ -564,27 +469,10 @@ RestClient 类是对于 REST API 的直接封装。它只包含一个 sql() 方
|
|||
|
||||
类似上文介绍的使用方法,增加 `req_id` 参数。
|
||||
|
||||
##### RestClient 类的使用
|
||||
|
||||
`RestClient` 类是对于 [REST API](../rest-api) 的直接封装。它只包含一个 `sql()` 方法用于执行任意 SQL 语句, 并返回执行结果。
|
||||
|
||||
```python title="RestClient 的使用"
|
||||
{{#include docs/examples/python/rest_client_with_req_id_example.py}}
|
||||
```python
|
||||
{{#include docs/examples/python/insert_rest.py:req_id}}
|
||||
```
|
||||
|
||||
对于 `sql()` 方法更详细的介绍, 请参考 [RestClient](https://docs.taosdata.com/api/taospy/taosrest/restclient.html)。
|
||||
|
||||
##### TaosRestCursor 类的使用
|
||||
|
||||
`TaosRestCursor` 类是对 PEP249 Cursor 接口的实现。
|
||||
|
||||
```python title="TaosRestCursor 的使用"
|
||||
{{#include docs/examples/python/connect_rest_with_req_id_examples.py:basic}}
|
||||
```
|
||||
- `cursor.execute` : 用来执行任意 SQL 语句。
|
||||
- `cursor.rowcount`: 对于写入操作返回写入成功记录数。对于查询操作,返回结果集行数。
|
||||
- `cursor.description` : 返回字段的描述信息。关于描述信息的具体格式请参考[TaosRestCursor](https://docs.taosdata.com/api/taospy/taosrest/cursor.html)。
|
||||
|
||||
</TabItem>
|
||||
|
||||
<TabItem value="websocket" label="WebSocket 连接">
|
||||
|
@ -592,36 +480,7 @@ RestClient 类是对于 REST API 的直接封装。它只包含一个 sql() 方
|
|||
类似上文介绍的使用方法,增加 `req_id` 参数。
|
||||
|
||||
```python
|
||||
{{#include docs/examples/python/connect_websocket_with_req_id_examples.py:basic}}
|
||||
```
|
||||
|
||||
- `conn.execute`: 用来执行任意 SQL 语句,返回影响的行数
|
||||
- `conn.query`: 用来执行查询 SQL 语句,返回查询结果
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
### 与 pandas 一起使用
|
||||
|
||||
<Tabs defaultValue="rest">
|
||||
<TabItem value="native" label="原生连接">
|
||||
|
||||
```python
|
||||
{{#include docs/examples/python/conn_native_pandas.py}}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="rest" label="REST 连接">
|
||||
|
||||
```python
|
||||
{{#include docs/examples/python/conn_rest_pandas.py}}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="websocket" label="WebSocket 连接">
|
||||
|
||||
```python
|
||||
{{#include docs/examples/python/conn_websocket_pandas.py}}
|
||||
{{#include docs/examples/python/insert_ws.py:req_id}}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
|
@ -634,130 +493,15 @@ TDengine 的 Python 连接器支持参数绑定风格的 Prepare API 方式写
|
|||
<Tabs>
|
||||
<TabItem value="native" label="原生连接">
|
||||
|
||||
##### 创建 stmt
|
||||
|
||||
Python 连接器的 `Connection` 提供了 `statement` 方法用于创建参数绑定对象 stmt,该方法接收 sql 字符串作为参数,sql 字符串目前仅支持用 `?` 来代表绑定的参数。
|
||||
|
||||
```
|
||||
import taos
|
||||
|
||||
conn = taos.connect()
|
||||
stmt = conn.statement("insert into log values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)")
|
||||
```
|
||||
|
||||
##### 参数绑定
|
||||
|
||||
调用 `new_multi_binds` 函数创建 params 列表,用于参数绑定。
|
||||
|
||||
```
|
||||
params = new_multi_binds(16)
|
||||
params[0].timestamp((1626861392589, 1626861392590, 1626861392591))
|
||||
params[1].bool((True, None, False))
|
||||
params[2].tinyint([-128, -128, None]) # -128 is tinyint null
|
||||
params[3].tinyint([0, 127, None])
|
||||
params[4].smallint([3, None, 2])
|
||||
params[5].int([3, 4, None])
|
||||
params[6].bigint([3, 4, None])
|
||||
params[7].tinyint_unsigned([3, 4, None])
|
||||
params[8].smallint_unsigned([3, 4, None])
|
||||
params[9].int_unsigned([3, 4, None])
|
||||
params[10].bigint_unsigned([3, 4, None])
|
||||
params[11].float([3, None, 1])
|
||||
params[12].double([3, None, 1.2])
|
||||
params[13].binary(["abc", "dddafadfadfadfadfa", None])
|
||||
params[14].nchar(["涛思数据", None, "a long string with 中文字符"])
|
||||
params[15].timestamp([None, None, 1626861392591])
|
||||
```
|
||||
|
||||
调用 stmt 的 `bind_param` 以单行的方式设置 values 或 `bind_param_batch` 以多行的方式设置 values 方法绑定参数。
|
||||
|
||||
```
|
||||
stmt.bind_param_batch(params)
|
||||
```
|
||||
|
||||
##### 执行 sql
|
||||
|
||||
调用 stmt 的 `execute` 方法执行 sql
|
||||
|
||||
```
|
||||
stmt.execute()
|
||||
```
|
||||
|
||||
##### 关闭 stmt
|
||||
|
||||
最后需要关闭 stmt。
|
||||
|
||||
```
|
||||
stmt.close()
|
||||
```
|
||||
|
||||
##### 示例代码
|
||||
|
||||
```python
|
||||
{{#include docs/examples/python/stmt_example.py}}
|
||||
{{#include docs/examples/python/stmt_native.py:stmt}}
|
||||
```
|
||||
</TabItem>
|
||||
|
||||
<TabItem value="websocket" label="WebSocket 连接">
|
||||
|
||||
##### 创建 stmt
|
||||
|
||||
Python WebSocket 连接器的 `Connection` 提供了 `statement` 方法用于创建参数绑定对象 stmt,该方法接收 sql 字符串作为参数,sql 字符串目前仅支持用 `?` 来代表绑定的参数。
|
||||
|
||||
```
|
||||
import taosws
|
||||
|
||||
conn = taosws.connect('taosws://localhost:6041/test')
|
||||
stmt = conn.statement()
|
||||
```
|
||||
|
||||
##### 解析 sql
|
||||
|
||||
调用 stmt 的 `prepare` 方法来解析 insert 语句。
|
||||
|
||||
```
|
||||
stmt.prepare("insert into t1 values (?, ?, ?, ?)")
|
||||
```
|
||||
|
||||
##### 参数绑定
|
||||
|
||||
调用 stmt 的 `bind_param` 方法绑定参数。
|
||||
|
||||
```
|
||||
stmt.bind_param([
|
||||
taosws.millis_timestamps_to_column([1686844800000, 1686844801000, 1686844802000, 1686844803000]),
|
||||
taosws.ints_to_column([1, 2, 3, 4]),
|
||||
taosws.floats_to_column([1.1, 2.2, 3.3, 4.4]),
|
||||
taosws.varchar_to_column(['a', 'b', 'c', 'd']),
|
||||
])
|
||||
```
|
||||
|
||||
调用 stmt 的 `add_batch` 方法,将参数加入批处理。
|
||||
|
||||
```
|
||||
stmt.add_batch()
|
||||
```
|
||||
|
||||
##### 执行 sql
|
||||
|
||||
调用 stmt 的 `execute` 方法执行 sql
|
||||
|
||||
```
|
||||
stmt.execute()
|
||||
```
|
||||
|
||||
##### 关闭 stmt
|
||||
|
||||
最后需要关闭 stmt。
|
||||
|
||||
```
|
||||
stmt.close()
|
||||
```
|
||||
|
||||
##### 示例代码
|
||||
|
||||
```python
|
||||
{{#include docs/examples/python/stmt_websocket_example.py}}
|
||||
{{#include docs/examples/python/stmt_ws.py:stmt}}
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
@ -767,46 +511,18 @@ stmt.close()
|
|||
连接器支持无模式写入功能。
|
||||
|
||||
<Tabs defaultValue="list">
|
||||
<TabItem value="list" label="List 写入">
|
||||
|
||||
##### 简单写入
|
||||
<TabItem value="list" label="原生连接">
|
||||
|
||||
```python
|
||||
{{#include docs/examples/python/schemaless_insert.py}}
|
||||
```
|
||||
|
||||
##### 带有 ttl 参数的写入
|
||||
|
||||
```python
|
||||
{{#include docs/examples/python/schemaless_insert_ttl.py}}
|
||||
```
|
||||
|
||||
##### 带有 req_id 参数的写入
|
||||
|
||||
```python
|
||||
{{#include docs/examples/python/schemaless_insert_req_id.py}}
|
||||
{{#include docs/examples/python/schemaless_native.py}}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
|
||||
<TabItem value="raw" label="Raw 写入">
|
||||
|
||||
##### 简单写入
|
||||
<TabItem value="raw" label="WebSocket 连接">
|
||||
|
||||
```python
|
||||
{{#include docs/examples/python/schemaless_insert_raw.py}}
|
||||
```
|
||||
|
||||
##### 带有 ttl 参数的写入
|
||||
|
||||
```python
|
||||
{{#include docs/examples/python/schemaless_insert_raw_ttl.py}}
|
||||
```
|
||||
|
||||
##### 带有 req_id 参数的写入
|
||||
|
||||
```python
|
||||
{{#include docs/examples/python/schemaless_insert_raw_req_id.py}}
|
||||
{{#include docs/examples/python/schemaless_ws.py}}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
|
@ -814,14 +530,15 @@ stmt.close()
|
|||
|
||||
### 执行带有 reqId 的无模式写入
|
||||
|
||||
连接器的 `schemaless_insert` 和 `schemaless_insert_raw` 方法支持 `req_id` 可选参数,此 `req_Id` 可用于请求链路追踪。
|
||||
连接器的 `schemaless_insert` 和 `schemaless_insert_raw` 方法支持 `req_id` 可选参数,此 `req_id` 可用于请求链路追踪。
|
||||
|
||||
```python
|
||||
{{#include docs/examples/python/schemaless_insert_req_id.py}}
|
||||
```
|
||||
|
||||
```python
|
||||
{{#include docs/examples/python/schemaless_insert_raw_req_id.py}}
|
||||
conn.schemaless_insert(
|
||||
lines=lineDemo,
|
||||
protocol=taos.SmlProtocol.LINE_PROTOCOL,
|
||||
precision=taos.SmlPrecision.NANO_SECONDS,
|
||||
req_id=1,
|
||||
)
|
||||
```
|
||||
|
||||
### 数据订阅
|
||||
|
@ -830,194 +547,56 @@ stmt.close()
|
|||
|
||||
#### 创建 Topic
|
||||
|
||||
创建 Topic 相关请参考 [数据订阅文档](../../develop/tmq/#创建-topic)。
|
||||
```python
|
||||
{{#include docs/examples/python/tmq_native.py:create_topic}}
|
||||
```
|
||||
|
||||
#### 创建 Consumer
|
||||
|
||||
<Tabs defaultValue="native">
|
||||
|
||||
<TabItem value="native" label="原生连接">
|
||||
|
||||
`Consumer` 提供了 Python 连接器订阅 TMQ 数据的 API。创建 Consumer 语法为 `consumer = Consumer(configs)`,参数定义请参考 [数据订阅文档](../../develop/tmq/#创建消费者-consumer)。
|
||||
|
||||
```python
|
||||
from taos.tmq import Consumer
|
||||
|
||||
consumer = Consumer({"group.id": "local", "td.connect.ip": "127.0.0.1"})
|
||||
{{#include docs/examples/python/tmq_native.py:create_consumer}}
|
||||
```
|
||||
</TabItem>
|
||||
|
||||
<TabItem value="websocket" label="WebSocket 连接">
|
||||
|
||||
除了原生的连接方式,Python 连接器还支持通过 websocket 订阅 TMQ 数据,使用 websocket 方式订阅 TMQ 数据需要安装 `taos-ws-py`。
|
||||
|
||||
taosws `Consumer` API 提供了基于 Websocket 订阅 TMQ 数据的 API。创建 Consumer 语法为 `consumer = Consumer(conf=configs)`,使用时需要指定 `td.connect.websocket.scheme` 参数值为 "ws",参数定义请参考 [数据订阅文档](../../develop/tmq/#%E5%88%9B%E5%BB%BA%E6%B6%88%E8%B4%B9%E8%80%85-consumer)。
|
||||
|
||||
```python
|
||||
import taosws
|
||||
|
||||
consumer = taosws.Consumer(conf={"group.id": "local", "td.connect.websocket.scheme": "ws"})
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
#### 订阅 topics
|
||||
|
||||
<Tabs defaultValue="native">
|
||||
|
||||
<TabItem value="native" label="原生连接">
|
||||
|
||||
Consumer API 的 `subscribe` 方法用于订阅 topics,consumer 支持同时订阅多个 topic。
|
||||
|
||||
```python
|
||||
consumer.subscribe(['topic1', 'topic2'])
|
||||
{{#include docs/examples/python/tmq_native.py:subscribe}}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="websocket" label="WebSocket 连接">
|
||||
|
||||
Consumer API 的 `subscribe` 方法用于订阅 topics,consumer 支持同时订阅多个 topic。
|
||||
|
||||
```python
|
||||
consumer.subscribe(['topic1', 'topic2'])
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
#### 消费数据
|
||||
|
||||
<Tabs defaultValue="native">
|
||||
|
||||
<TabItem value="native" label="原生连接">
|
||||
|
||||
Consumer API 的 `poll` 方法用于消费数据,`poll` 方法接收一个 float 类型的超时时间,超时时间单位为秒(s),`poll` 方法在超时之前返回一条 Message 类型的数据或超时返回 `None`。消费者必须通过 Message 的 `error()` 方法校验返回数据的 error 信息。
|
||||
|
||||
```python
|
||||
while True:
|
||||
message = consumer.poll(1)
|
||||
if not message:
|
||||
continue
|
||||
err = message.error()
|
||||
if err is not None:
|
||||
raise err
|
||||
val = message.value()
|
||||
|
||||
for block in val:
|
||||
print(block.fetchall())
|
||||
{{#include docs/examples/python/tmq_native.py:consume}}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="websocket" label="WebSocket 连接">
|
||||
|
||||
Consumer API 的 `poll` 方法用于消费数据,`poll` 方法接收一个 float 类型的超时时间,超时时间单位为秒(s),`poll` 方法在超时之前返回一条 Message 类型的数据或超时返回 `None`。
|
||||
|
||||
```python
|
||||
while True:
|
||||
message = consumer.poll(1)
|
||||
if not message:
|
||||
continue
|
||||
|
||||
for block in message:
|
||||
for row in block:
|
||||
print(row)
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
#### 获取消费进度
|
||||
|
||||
<Tabs defaultValue="native">
|
||||
|
||||
<TabItem value="native" label="原生连接">
|
||||
|
||||
Consumer API 的 `assignment` 方法用于获取 Consumer 订阅的所有 topic 的消费进度,返回结果类型为 TopicPartition 列表。
|
||||
|
||||
```python
|
||||
assignments = consumer.assignment()
|
||||
{{#include docs/examples/python/tmq_native.py:assignment}}
|
||||
```
|
||||
|
||||
Consumer API 的 `seek` 方法用于重置 Consumer 的消费进度到指定位置,方法参数类型为 TopicPartition。
|
||||
|
||||
```python
|
||||
tp = TopicPartition(topic='topic1', partition=0, offset=0)
|
||||
consumer.seek(tp)
|
||||
{{#include docs/examples/python/tmq_native.py:consume}}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="websocket" label="WebSocket 连接">
|
||||
|
||||
Consumer API 的 `assignment` 方法用于获取 Consumer 订阅的所有 topic 的消费进度,返回结果类型为 TopicPartition 列表。
|
||||
|
||||
```python
|
||||
assignments = consumer.assignment()
|
||||
```
|
||||
|
||||
Consumer API 的 `seek` 方法用于重置 Consumer 的消费进度到指定位置。
|
||||
|
||||
```python
|
||||
consumer.seek(topic='topic1', partition=0, offset=0)
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
#### 关闭订阅
|
||||
|
||||
<Tabs defaultValue="native">
|
||||
|
||||
<TabItem value="native" label="原生连接">
|
||||
|
||||
消费结束后,应当取消订阅,并关闭 Consumer。
|
||||
|
||||
```python
|
||||
consumer.unsubscribe()
|
||||
consumer.close()
|
||||
{{#include docs/examples/python/tmq_native.py:unsubscribe}}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="websocket" label="WebSocket 连接">
|
||||
|
||||
消费结束后,应当取消订阅,并关闭 Consumer。
|
||||
|
||||
```python
|
||||
consumer.unsubscribe()
|
||||
consumer.close()
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
#### 完整示例
|
||||
|
||||
<Tabs defaultValue="native">
|
||||
|
||||
<TabItem value="native" label="原生连接">
|
||||
|
||||
```python
|
||||
{{#include docs/examples/python/tmq_example.py}}
|
||||
{{#include docs/examples/python/tmq_native.py}}
|
||||
```
|
||||
|
||||
```python
|
||||
{{#include docs/examples/python/tmq_assignment_example.py:taos_get_assignment_and_seek_demo}}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="websocket" label="WebSocket 连接">
|
||||
|
||||
```python
|
||||
{{#include docs/examples/python/tmq_websocket_example.py}}
|
||||
```
|
||||
|
||||
```python
|
||||
{{#include docs/examples/python/tmq_websocket_assgnment_example.py:taosws_get_assignment_and_seek_demo}}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
### 更多示例程序
|
||||
|
||||
| 示例程序链接 | 示例程序内容 |
|
||||
|
|
|
@ -6,337 +6,328 @@ title: TDengine Node.js Connector
|
|||
|
||||
import Tabs from "@theme/Tabs";
|
||||
import TabItem from "@theme/TabItem";
|
||||
import RequestId from "./_request_id.mdx";
|
||||
|
||||
import Preparation from "./_preparation.mdx";
|
||||
import NodeInsert from "../07-develop/03-insert-data/_js_sql.mdx";
|
||||
import NodeInfluxLine from "../07-develop/03-insert-data/_js_line.mdx";
|
||||
import NodeOpenTSDBTelnet from "../07-develop/03-insert-data/_js_opts_telnet.mdx";
|
||||
import NodeOpenTSDBJson from "../07-develop/03-insert-data/_js_opts_json.mdx";
|
||||
import NodeQuery from "../07-develop/04-query-data/_js.mdx";
|
||||
`@tdengine/websocket` 是 TDengine 的官方 Node.js 语言连接器。Node.js 开发人员可以通过它开发存取 TDengine 数据库的的应用软件。
|
||||
|
||||
`@tdengine/client` 和 `@tdengine/rest` 是 TDengine 的官方 Node.js 语言连接器。 Node.js 开发人员可以通过它开发可以存取 TDengine 集群数据的应用软件。注意:从 TDengine 3.0 开始 Node.js 原生连接器的包名由 `td2.0-connector` 改名为 `@tdengine/client` 而 rest 连接器的包名由 `td2.0-rest-connector` 改为 `@tdengine/rest`。并且不与 TDengine 2.x 兼容。
|
||||
Node.js 连接器源码托管在 [GitHub](https://github.com/taosdata/taos-connector-node/tree/main)。
|
||||
|
||||
`@tdengine/client` 是**原生连接器**,它通过 TDengine 客户端驱动程序(taosc)连接 TDengine 运行实例,支持数据写入、查询、订阅、schemaless 接口和参数绑定接口等功能。`@tdengine/rest` 是 **REST 连接器**,它通过 taosAdapter 提供的 REST 接口连接 TDengine 的运行实例。REST 连接器可以在任何平台运行,但性能略为下降,接口实现的功能特性集合和原生接口有少量不同。
|
||||
## 连接方式
|
||||
|
||||
Node.js 连接器源码托管在 [GitHub](https://github.com/taosdata/taos-connector-node/tree/3.0)。
|
||||
Node.js 连接器目前仅支持 Websocket 连接器, 其通过 taosAdapter 提供的 Websocket 接口连接 TDengine 实例。
|
||||
|
||||
连接方式的详细介绍请参考:[连接器建立连接的方式](../../develop/connect/#连接器建立连接的方式)
|
||||
|
||||
## 支持的平台
|
||||
|
||||
原生连接器支持的平台和 TDengine 客户端驱动支持的平台一致。
|
||||
REST 连接器支持所有能运行 Node.js 的平台。
|
||||
支持 Node.js 14及以上版本。
|
||||
|
||||
## 版本支持
|
||||
## 版本历史
|
||||
|
||||
请参考[版本支持列表](../#版本支持)
|
||||
| Node.js 连接器 版本 | 主要变化 | TDengine 版本 |
|
||||
| :------------------: | :----------------------: | :----------------: |
|
||||
| 3.1.0 | 新版本发布,支持 WebSocket 连接 | 3.2.0.0 及更高版本 |
|
||||
|
||||
## 支持的功能特性
|
||||
|
||||
<Tabs defaultValue="native">
|
||||
<TabItem value="native" label="原生连接器">
|
||||
- 连接管理
|
||||
- SQL写入
|
||||
- SQL查询
|
||||
- 参数绑定
|
||||
- 数据订阅
|
||||
- 无模式写入
|
||||
|
||||
1. 连接管理
|
||||
2. 普通查询
|
||||
3. 连续查询
|
||||
4. 参数绑定
|
||||
5. 订阅功能
|
||||
6. Schemaless
|
||||
## 处理异常
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="rest" label="REST 连接器">
|
||||
在调用连接器 api 报错后,通过 try catch 可以获取到错误的信息和错误码。
|
||||
|
||||
1. 连接管理
|
||||
2. 普通查询
|
||||
3. 连续查询
|
||||
错误说明:Node.js 连接器错误码在 100 到 110 之间,之外的错误为 TDengine 其他功能模块的报错。
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
具体的连接器错误码请参考:
|
||||
|
||||
| Error Code | Description | Suggested Actions |
|
||||
| ---------- | -------------------------------------------------------------| ----------------------------------------------------------------------------------------- |
|
||||
| 100 | invalid variables | 参数不合法,请检查相应接口规范,调整参数类型及大小。 |
|
||||
| 101 | invalid url | url 错误,请检查 url 是否填写正确。 |
|
||||
| 102 | received server data but did not find a callback for processing | 接收到服务端数据但没有找到上层回调 |
|
||||
| 103 | invalid message type | 接收到的消息类型无法识别,请检查服务端是否正常。 |
|
||||
| 104 | connection creation failed | 连接创建失败,请检查网络是否正常。 |
|
||||
| 105 | websocket request timeout | 请求超时 |
|
||||
| 106 | authentication fail | 认证失败,请检查用户名,密码是否正确。 |
|
||||
| 107 | unknown sql type in tdengine | 请检查 TDengine 支持的 Data Type 类型。 |
|
||||
| 108 | connection has been closed | 连接已经关闭,请检查 Connection 是否关闭后再次使用,或是连接是否正常。 |
|
||||
| 109 | fetch block data parse fail | 获取到的查询数据,解析失败 |
|
||||
| 110 | websocket connection has reached its maximum limit | Websocket 连接达到上限 |
|
||||
|
||||
## 类型映射
|
||||
|
||||
下表为 TDengine DataType 和 Node.js DataType 之间的映射关系
|
||||
|
||||
| TDengine DataType | Node.js DataType|
|
||||
|-------------------|-------------|
|
||||
| TIMESTAMP | bigint |
|
||||
| TINYINT | number |
|
||||
| SMALLINT | number |
|
||||
| INT | number |
|
||||
| BIGINT | bigint |
|
||||
| TINYINT UNSIGNED | number |
|
||||
| SMALLINT UNSIGNED | number |
|
||||
| INT UNSIGNED | number |
|
||||
| BIGINT UNSIGNED | bigint |
|
||||
| FLOAT | number |
|
||||
| DOUBLE | number |
|
||||
| BOOL | boolean |
|
||||
| BINARY | string |
|
||||
| NCHAR | string |
|
||||
| JSON | string |
|
||||
| VARBINARY | ArrayBuffer |
|
||||
| GEOMETRY | ArrayBuffer |
|
||||
|
||||
**注意**:JSON 类型仅在 tag 中支持。
|
||||
|
||||
## 安装步骤
|
||||
|
||||
### 安装前准备
|
||||
|
||||
- 安装 Node.js 开发环境
|
||||
- 如果使用 REST 连接器,跳过此步。但如果使用原生连接器,请安装 TDengine 客户端驱动,具体步骤请参考[安装客户端驱动](../#安装客户端驱动)。我们使用 [node-gyp](https://github.com/nodejs/node-gyp) 和 TDengine 实例进行交互,还需要根据具体操作系统来安装下文提到的一些依赖工具。
|
||||
- 安装 Node.js 开发环境, 使用14以上版本。下载链接: https://nodejs.org/en/download/
|
||||
|
||||
<Tabs defaultValue="Linux">
|
||||
<TabItem value="Linux" label="Linux 系统安装依赖工具">
|
||||
|
||||
- `python` (建议`v2.7` , `v3.x.x` 目前还不支持)
|
||||
- `@tdengine/client` 3.0.0 支持 Node.js LTS v10.9.0 或更高版本, Node.js LTS v12.8.0 或更高版本;其他版本可能存在包兼容性的问题
|
||||
- `make`
|
||||
- C 语言编译器,[GCC](https://gcc.gnu.org) v4.8.5 或更高版本
|
||||
|
||||
</TabItem>
|
||||
|
||||
<TabItem value="macOS" label="macOS 系统安装依赖工具">
|
||||
|
||||
- `python` (建议`v2.7` , `v3.x.x` 目前还不支持)
|
||||
- `@tdengine/client` 3.0.0 目前是只支持 Node.js v12.22.12 或 v12 的更高版本;其他版本可能存在包兼容性的问题
|
||||
- `make`
|
||||
- C 语言编译器,[GCC](https://gcc.gnu.org) v4.8.5 或更高版本
|
||||
|
||||
</TabItem>
|
||||
|
||||
<TabItem value="Windows" label="Windows 系统安装依赖工具">
|
||||
|
||||
- 安装方法 1
|
||||
|
||||
使用微软的[ windows-build-tools ](https://github.com/felixrieseberg/windows-build-tools)在`cmd` 命令行界面执行`npm install --global --production windows-build-tools` 即可安装所有的必备工具。
|
||||
|
||||
- 安装方法 2
|
||||
|
||||
手动安装以下工具:
|
||||
|
||||
- 安装 Visual Studio 相关:[Visual Studio Build 工具](https://visualstudio.microsoft.com/thank-you-downloading-visual-studio/?sku=BuildTools) 或者 [Visual Studio 2017 Community](https://visualstudio.microsoft.com/pl/thank-you-downloading-visual-studio/?sku=Community)
|
||||
- 安装 [Python](https://www.python.org/downloads/) 2.7(`v3.x.x` 暂不支持) 并执行 `npm config set python python2.7`
|
||||
- 进入`cmd`命令行界面,`npm config set msvs_version 2017`
|
||||
|
||||
参考微软的 Node.js 用户手册[ Microsoft's Node.js Guidelines for Windows](https://github.com/Microsoft/nodejs-guidelines/blob/master/windows-environment.md#compiling-native-addon-modules)。
|
||||
|
||||
如果在 Windows 10 ARM 上使用 ARM64 Node.js,还需添加 "Visual C++ compilers and libraries for ARM64" 和 "Visual C++ ATL for ARM64"。
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
### 使用 npm 安装
|
||||
|
||||
<Tabs defaultValue="install_rest">
|
||||
<TabItem value="install_native" label="安装原生连接器">
|
||||
### 使用 npm 安装 Node.js 连接器
|
||||
|
||||
```bash
|
||||
npm install @tdengine/client
|
||||
npm install @tdengine/websocket
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="install_rest" label="安装 REST 连接器">
|
||||
|
||||
```bash
|
||||
npm install @tdengine/rest
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
### 安装验证
|
||||
|
||||
<Tabs defaultValue="native">
|
||||
<TabItem value="native" label="原生连接器">
|
||||
|
||||
在安装好 TDengine 客户端后,使用 nodejsChecker.js 程序能够验证当前环境是否支持 Node.js 方式访问 TDengine。
|
||||
|
||||
验证方法:
|
||||
|
||||
- 新建安装验证目录,例如:`~/tdengine-test`,下载 GitHub 上 [nodejsChecker.js 源代码](https://github.com/taosdata/taos-connector-node/blob/3.0/nodejs/examples/nodejsChecker.js)到本地。
|
||||
- 新建安装验证目录,例如:`~/tdengine-test`,下载 GitHub 上 [nodejsChecker.js 源代码](https://github.com/taosdata/TDengine/tree/main/docs/examples/node/websocketexample/nodejsChecker.js)到本地。
|
||||
|
||||
- 在命令行中执行以下命令。
|
||||
|
||||
```bash
|
||||
npm init -y
|
||||
npm install @tdengine/client
|
||||
node nodejsChecker.js host=localhost
|
||||
npm init -y
|
||||
npm install @tdengine/websocket
|
||||
node nodejsChecker.js
|
||||
```
|
||||
|
||||
- 执行以上步骤后,在命令行会输出 nodejsChecker.js 连接 TDengine 实例,并执行简单插入和查询的结果。
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="rest" label="REST 连接器">
|
||||
|
||||
在安装好 TDengine 客户端后,使用 nodejsChecker.js 程序能够验证当前环境是否支持 Node.js 方式访问 TDengine。
|
||||
|
||||
验证方法:
|
||||
|
||||
- 新建安装验证目录,例如:`~/tdengine-test`,下载 GitHub 上 [restChecker.js 源代码](https://github.com/taosdata/TDengine/tree/3.0/docs/examples/node/restexample/restChecker.js)到本地。
|
||||
|
||||
- 在命令行中执行以下命令。
|
||||
|
||||
```bash
|
||||
npm init -y
|
||||
npm install @tdengine/rest
|
||||
node restChecker.js
|
||||
```
|
||||
|
||||
- 执行以上步骤后,在命令行会输出 restChecker.js 连接 TDengine 实例,并执行简单插入和查询的结果。
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
|
||||
- 执行以上步骤后,在命令行会输出 nodeChecker.js 连接 TDengine 实例,并执行简单插入和查询的结果。
|
||||
|
||||
## 建立连接
|
||||
|
||||
请选择使用一种连接器。
|
||||
|
||||
<Tabs defaultValue="native">
|
||||
<TabItem value="native" label="原生连接">
|
||||
|
||||
安装并引用 `@tdengine/client` 包。
|
||||
安装并引用 `@tdengine/websocket` 包。
|
||||
|
||||
**注意**:
|
||||
- 链接器使用结束后,需要调用 taos.destroy() 释放连接器资源
|
||||
```javascript
|
||||
//A cursor also needs to be initialized in order to interact with TDengine from Node.js.
|
||||
const taos = require("@tdengine/client");
|
||||
var conn = taos.connect({
|
||||
host: "127.0.0.1",
|
||||
user: "root",
|
||||
password: "taosdata",
|
||||
config: "/etc/taos",
|
||||
port: 0,
|
||||
});
|
||||
var cursor = conn.cursor(); // Initializing a new cursor
|
||||
const taos = require("@tdengine/websocket");
|
||||
|
||||
//Close a connection
|
||||
conn.close();
|
||||
//数据库操作......
|
||||
|
||||
taos.destroy();
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="rest" label="REST 连接">
|
||||
|
||||
安装并引用 `@tdengine/rest` 包。
|
||||
|
||||
```javascript
|
||||
//A cursor also needs to be initialized in order to interact with TDengine from Node.js.
|
||||
import { options, connect } from "@tdengine/rest";
|
||||
options.path = "/rest/sql";
|
||||
// set host
|
||||
options.host = "localhost";
|
||||
// set other options like user/passwd
|
||||
|
||||
let conn = connect(options);
|
||||
let cursor = conn.cursor();
|
||||
WSConfig配置Websocket参数如下:
|
||||
getToken(): string | undefined | null;
|
||||
setToken(token: string): void;
|
||||
getUser(): string | undefined | null;
|
||||
setUser(user: string): void;
|
||||
getPwd(): string | undefined | null;
|
||||
setPwd(pws: string): void;
|
||||
getDb(): string | undefined | null;
|
||||
setDb(db: string): void;
|
||||
getUrl(): string;
|
||||
setUrl(url: string): void;
|
||||
setTimeOut(ms: number): void;
|
||||
getTimeOut(): number | undefined | null;
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
```javascript
|
||||
{{#include docs/examples/node/websocketexample/sql_example.js:createConnect}}
|
||||
```
|
||||
|
||||
## 使用示例
|
||||
|
||||
### 写入数据
|
||||
### 创建数据库和表
|
||||
|
||||
#### SQL 写入
|
||||
```javascript
|
||||
{{#include docs/examples/node/websocketexample/sql_example.js:create_db_and_table}}
|
||||
```
|
||||
> **注意**:如果不使用 `USE power` 指定数据库,则后续对表的操作都需要增加数据库名称作为前缀,如 power.meters。
|
||||
|
||||
<Tabs defaultValue="native">
|
||||
<TabItem value="native" label="原生连接">
|
||||
### 插入数据
|
||||
|
||||
<NodeInsert />
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="rest" label="REST 连接">
|
||||
|
||||
```js
|
||||
{{#include docs/examples/node/restexample/insert_example.js}}
|
||||
```javascript
|
||||
{{#include docs/examples/node/websocketexample/sql_example.js:insertData}}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
|
||||
|
||||
#### InfluxDB 行协议写入
|
||||
|
||||
<Tabs defaultValue="native">
|
||||
<TabItem value="native" label="原生连接">
|
||||
|
||||
<NodeInfluxLine />
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
#### OpenTSDB Telnet 行协议写入
|
||||
|
||||
<Tabs defaultValue="native">
|
||||
<TabItem value="native" label="原生连接">
|
||||
|
||||
<NodeOpenTSDBTelnet />
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
#### OpenTSDB JSON 行协议写入
|
||||
|
||||
<Tabs defaultValue="native">
|
||||
<TabItem value="native" label="原生连接">
|
||||
|
||||
<NodeOpenTSDBJson />
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
> NOW 为系统内部函数,默认为客户端所在计算机当前时间。
|
||||
> `NOW + 1s` 代表客户端当前时间往后加 1 秒,数字后面代表时间单位:a(毫秒),s(秒),m(分),h(小时),d(天),w(周),n(月),y(年)。
|
||||
|
||||
### 查询数据
|
||||
|
||||
<Tabs defaultValue="native">
|
||||
<TabItem value="native" label="原生连接">
|
||||
|
||||
<NodeQuery />
|
||||
|
||||
</TabItem>
|
||||
|
||||
<TabItem value="rest" label="REST 连接">
|
||||
|
||||
```js
|
||||
{{#include docs/examples/node/restexample/query_example.js}}
|
||||
```javascript
|
||||
{{#include docs/examples/node/websocketexample/sql_example.js:queryData}}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
> 查询到的数据
|
||||
|
||||
```javascript
|
||||
wsRow:meta:=> [
|
||||
{ name: 'ts', type: 'TIMESTAMP', length: 8 },
|
||||
{ name: 'current', type: 'FLOAT', length: 4 },
|
||||
{ name: 'voltage', type: 'INT', length: 4 },
|
||||
{ name: 'phase', type: 'FLOAT', length: 4 },
|
||||
{ name: 'location', type: 'VARCHAR', length: 64},
|
||||
{ name: 'groupid', type: 'INT', length: 4 }
|
||||
]
|
||||
wsRow:data:=> [
|
||||
[ 1714013737536n, 12.3, 221, 0.31, 'California.SanFrancisco', 3 ]
|
||||
]
|
||||
```
|
||||
|
||||
### 执行带有 reqId 的 SQL
|
||||
|
||||
<RequestId />
|
||||
|
||||
```javascript
|
||||
{{#include docs/examples/node/websocketexample/sql_example.js:sqlWithReqid}}
|
||||
```
|
||||
|
||||
### 通过参数绑定写入数据
|
||||
|
||||
TDengine 的 NodeJs 连接器支持参数绑定风格的 Prepare API 方式写入数据,和大多数数据库类似,目前仅支持用 ? 来代表待绑定的参数。采用这种方式写入数据时,能避免 SQL 语法解析的资源消耗,从而在很多情况下显著提升写入性能。
|
||||
|
||||
**注意**:
|
||||
- 预处理语句中指定数据库与子表名称不要使用 `db.?`,应直接使用 `?`,然后在 setTableName 中指定数据库,如:`stmt.setTableName("db.t1")`。
|
||||
|
||||
示例代码:
|
||||
```javascript
|
||||
{{#include docs/examples/node/websocketexample/stmt_example.js}}
|
||||
```
|
||||
|
||||
用于设定 TAG/VALUES 数据列的取值的方法总共有:
|
||||
|
||||
```javascript
|
||||
setBoolean(params: any[]): void;
|
||||
setTinyInt(params: any[]): void;
|
||||
setUTinyInt(params: any[]): void;
|
||||
setSmallInt(params: any[]): void;
|
||||
setUSmallInt(params: any[]): void;
|
||||
setInt(params: any[]): void;
|
||||
setUInt(params: any[]): void;
|
||||
setBigint(params: any[]): void;
|
||||
setUBigint(params: any[]): void;
|
||||
setFloat(params: any[]): void;
|
||||
setDouble(params: any[]): void;
|
||||
setVarchar(params: any[]): void;
|
||||
setBinary(params: any[]): void;
|
||||
setNchar(params: any[]): void;
|
||||
setJson(params: any[]): void;
|
||||
setVarBinary(params: any[]): void;
|
||||
setGeometry(params: any[]): void;
|
||||
setTimestamp(params: any[]): void;
|
||||
```
|
||||
|
||||
**注意**:JSON 类型仅在 tag 中支持。
|
||||
|
||||
### 无模式写入
|
||||
|
||||
TDengine 支持无模式写入功能。无模式写入兼容 InfluxDB 的 行协议(Line Protocol)、OpenTSDB 的 telnet 行协议和 OpenTSDB 的 JSON 格式协议。详情请参见[无模式写入](../../reference/schemaless/)。
|
||||
|
||||
```javascript
|
||||
{{#include docs/examples/node/websocketexample/line_example.js}}
|
||||
```
|
||||
|
||||
### 执行带有 reqId 的无模式写入
|
||||
|
||||
此 reqId 可用于请求链路追踪。
|
||||
|
||||
```javascript
|
||||
await wsSchemaless.schemalessInsert([influxdbData], SchemalessProto.InfluxDBLineProtocol, Precision.NANO_SECONDS, ttl, reqId);
|
||||
await wsSchemaless.schemalessInsert([telnetData], SchemalessProto.OpenTSDBTelnetLineProtocol, Precision.NANO_SECONDS, ttl, reqId);
|
||||
await wsSchemaless.schemalessInsert([jsonData], SchemalessProto.OpenTSDBJsonFormatProtocol, Precision.NANO_SECONDS, ttl, reqId);
|
||||
```
|
||||
|
||||
### 数据订阅
|
||||
|
||||
TDengine NodeJs 连接器支持订阅功能,应用 API 如下:
|
||||
|
||||
#### 创建 Topic
|
||||
```javascript
|
||||
{{#include docs/examples/node/websocketexample/tmq_example.js:create_topic}}
|
||||
```
|
||||
|
||||
#### 创建 Consumer
|
||||
|
||||
```javascript
|
||||
{{#include docs/examples/node/websocketexample/tmq_example.js:create_consumer}}
|
||||
```
|
||||
> 参数说明
|
||||
- taos.TMQConstants.CONNECT_USER: 用户名。
|
||||
- taos.TMQConstants.CONNECT_PASS: 密码。
|
||||
- taos.TMQConstants.GROUP_ID: 所在的 group。
|
||||
- taos.TMQConstants.CLIENT_ID: client id。
|
||||
- taos.TMQConstants.WS_URL: taosAdapter 的url地址。
|
||||
- taos.TMQConstants.AUTO_OFFSET_RESET: 来确定消费位置为最新数据(latest)还是包含旧数据(earliest)。
|
||||
- taos.TMQConstants.ENABLE_AUTO_COMMIT: 是否允许自动提交。
|
||||
- taos.TMQConstants.AUTO_COMMIT_INTERVAL_MS: 自动提交间隔。
|
||||
- taos.TMQConstants.CONNECT_MESSAGE_TIMEOUT: 数据传输超时参数,单位 ms,默认为 10000 ms。
|
||||
|
||||
其他参数请参考:[Consumer 参数列表](../../develop/tmq/#数据订阅相关参数), 注意 TDengine 服务端自3.2.0.0版本开始消息订阅中的 auto.offset.reset 默认值发生变化。
|
||||
|
||||
#### 订阅消费数据
|
||||
```javascript
|
||||
{{#include docs/examples/node/websocketexample/tmq_example.js:subscribe}}
|
||||
```
|
||||
|
||||
#### 指定订阅 Offset
|
||||
|
||||
```javascript
|
||||
{{#include docs/examples/node/websocketexample/tmq_example.js:assignment}}
|
||||
```
|
||||
|
||||
#### 关闭订阅
|
||||
```javascript
|
||||
// 取消订阅
|
||||
consumer.unsubscribe();
|
||||
// 关闭消费
|
||||
consumer.close()
|
||||
// 释放连接器资源
|
||||
taos.destroy();
|
||||
```
|
||||
|
||||
详情请参考:[数据订阅](../../develop/tmq)
|
||||
|
||||
#### 完整示例
|
||||
|
||||
```javascript
|
||||
{{#include docs/examples/node/websocketexample/tmq_example.js}}
|
||||
```
|
||||
|
||||
## 更多示例程序
|
||||
|
||||
| 示例程序 | 示例程序描述 |
|
||||
| 示例程序 | 示例程序描述 |
|
||||
| ------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------- |
|
||||
| [basicUse](https://github.com/taosdata/taos-connector-node/blob/3.0/nodejs/examples/queryExample.js) | 基本的使用如如建立连接,执行 SQL 等操作。 |
|
||||
| [stmtBindBatch](https://github.com/taosdata/taos-connector-node/blob/3.0/nodejs/examples/bindParamBatch.js) | 绑定多行参数插入的示例。 | |
|
||||
| [stmtBindSingleParamBatch](https://github.com/taosdata/taos-connector-node/blob/3.0/nodejs/examples/bindSingleParamBatch.js) | 按列绑定参数插入的示例。 |
|
||||
| [stmtQuery](https://github.com/taosdata/taos-connector-node/blob/3.0/nodejs/examples/stmtQuery.js) | 绑定参数查询的示例。 |
|
||||
| [schemless insert](https://github.com/taosdata/taos-connector-node/blob/3.0/nodejs/examples/schemaless.js) | schemless 插入的示例。 |
|
||||
| [TMQ](https://github.com/taosdata/taos-connector-node/blob/3.0/nodejs/examples/tmq.js) | 订阅的使用示例。 |
|
||||
| [asyncQuery](https://github.com/taosdata/taos-connector-node/blob/3.0/nodejs/examples/asyncQueryExample.js) | 异步查询的使用示例。 |
|
||||
| [REST](https://github.com/taosdata/taos-connector-node/blob/3.0/typescript-rest/example/example.ts) | 使用 REST 连接的 TypeScript 使用示例。 |
|
||||
| [sql_example](https://github.com/taosdata/TDengine/tree/main/docs/examples/node/websocketexample/sql_example.js) | 基本的使用如如建立连接,执行 SQL 等操作。 |
|
||||
| [stmt_example](https://github.com/taosdata/TDengine/tree/main/docs/examples/node/websocketexample/stmt_example.js) | 绑定参数插入的示例。 | |
|
||||
| [line_example](https://github.com/taosdata/TDengine/tree/main/docs/examples/node/websocketexample/line_example.js) | 行协议写入示例。 |
|
||||
| [telnet_line_example](https://github.com/taosdata/TDengine/tree/main/docs/examples/node/websocketexample/telnet_line_example.js) | OpenTSDB Telnet 行协议写入示例。 |
|
||||
| [json_line_example](https://github.com/taosdata/TDengine/tree/main/docs/examples/node/websocketexample/json_line_example.js) | OpenTSDB JSON 行协议写入示例。 |
|
||||
| [tmq_example](https://github.com/taosdata/TDengine/tree/main/docs/examples/node/websocketexample/tmq_example.js) | 订阅的使用示例。 |
|
||||
|
||||
## 使用限制
|
||||
|
||||
native 连接器(`@tdengine/client`) >= v3.0.0 目前支持 node 的版本为:支持 >=v12.8.0 <= v12.9.1 || >=v10.20.0 <= v10.9.0 ;2.0.5 及更早版本支持 v10.x 版本,其他版本可能存在包兼容性的问题。
|
||||
- Node.js 连接器(`@tdengine/websocket`)支持 Node.js 14 以上版本,低于 14 的版本可能存在包兼容性的问题。
|
||||
- 目前只支持 WebSocket 连接,需要提前启动 taosAdapter
|
||||
- 使用连接器结束后,需要调用 taos.connectorDestroy(); 释放连接器资源。
|
||||
|
||||
## 其他说明
|
||||
|
||||
Node.js 连接器的使用参见[视频教程](https://www.taosdata.com/blog/2020/11/11/1957.html)。
|
||||
|
||||
## 常见问题
|
||||
|
||||
1. 使用 REST 连接需要启动 taosadapter。
|
||||
1. "Unable to establish connection" 或 "Unable to resolve FQDN"
|
||||
|
||||
```bash
|
||||
sudo systemctl start taosadapter
|
||||
```
|
||||
**原因**:一般都是因为配置 FQDN 不正确。 可以参考[如何彻底搞懂 TDengine 的 FQDN](https://www.taosdata.com/blog/2021/07/29/2741.html) 。
|
||||
|
||||
2. Node.js 版本
|
||||
|
||||
原生连接器 `@tdengine/client` 目前兼容的 Node.js 版本为:>=v10.20.0 <= v10.9.0 || >=v12.8.0 <= v12.9.1
|
||||
|
||||
3. "Unable to establish connection","Unable to resolve FQDN"
|
||||
|
||||
一般都是因为配置 FQDN 不正确。 可以参考[如何彻底搞懂 TDengine 的 FQDN](https://www.taosdata.com/blog/2021/07/29/2741.html) 。
|
||||
|
||||
## 重要更新记录
|
||||
|
||||
### 原生连接器
|
||||
|
||||
| package name | version | TDengine version | 说明 |
|
||||
|------------------|---------|---------------------|------------------------------------------------------------------|
|
||||
| @tdengine/client | 3.0.0 | 3.0.0 | 支持TDengine 3.0 且不与2.x 兼容。 |
|
||||
| td2.0-connector | 2.0.12 | 2.4.x;2.5.x;2.6.x | 修复 cursor.close() 报错的 bug。 |
|
||||
| td2.0-connector | 2.0.11 | 2.4.x;2.5.x;2.6.x | 支持绑定参数、json tag、schemaless 接口等功能。 |
|
||||
| td2.0-connector | 2.0.10 | 2.4.x;2.5.x;2.6.x | 支持连接管理,普通查询、连续查询、获取系统信息、订阅功能等功能。 |
|
||||
### REST 连接器
|
||||
|
||||
| package name | version | TDengine version | 说明 |
|
||||
|----------------------|---------|---------------------|---------------------------------------------------------------------------|
|
||||
| @tdengine/rest | 3.0.0 | 3.0.0 | 支持 TDegnine 3.0,且不与2.x 兼容。 |
|
||||
| td2.0-rest-connector | 1.0.7 | 2.4.x;2.5.x;2.6.x | 移除默认端口 6041。 |
|
||||
| td2.0-rest-connector | 1.0.6 | 2.4.x;2.5.x;2.6.x | 修复create,insert,update,alter 等SQL 执行返回的 affectRows 错误的bug。 |
|
||||
| td2.0-rest-connector | 1.0.5 | 2.4.x;2.5.x;2.6.x | 支持云服务 cloud Token; |
|
||||
| td2.0-rest-connector | 1.0.3 | 2.4.x;2.5.x;2.6.x | 支持连接管理、普通查询、获取系统信息、错误信息、连续查询等功能。 |
|
||||
|
||||
## API 参考
|
||||
|
||||
[API 参考](https://docs.taosdata.com/api/td2.0-connector/)
|
||||
|
|
|
@ -6,19 +6,22 @@ title: TDengine C# Connector
|
|||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
import RequestId from "./_request_id.mdx";
|
||||
|
||||
`TDengine.Connector` 是 TDengine 提供的 C# 语言连接器。C# 开发人员可以通过它开发存取 TDengine 集群数据的 C# 应用软件。
|
||||
|
||||
`TDengine.Connector` 连接器支持通过 TDengine 客户端驱动(taosc)建立与 TDengine 运行实例的连接,提供数据写入、查询、数据订阅、schemaless 数据写入、参数绑定接口数据写入等功能。 `TDengine.Connector` 自 v3.0.1 起还支持 WebSocket 连接,提供数据写入、查询、参数绑定接口数据写入等功能。
|
||||
## 连接方式
|
||||
|
||||
本文介绍如何在 Linux 或 Windows 环境中安装 `TDengine.Connector`,并通过 `TDengine.Connector` 连接 TDengine 集群,进行数据写入、查询等基本操作。
|
||||
`TDengine.Connector` 提供两种形式的连接器
|
||||
* **原生连接**,通过 TDengine 客户端驱动程序(taosc)原生连接 TDengine 实例,支持数据写入、查询、数据订阅、schemaless 接口和参数绑定接口等功能。
|
||||
* **Websocket 连接**,通过 taosAdapter 提供的 Websocket 接口连接 TDengine 实例,WebSocket 连接实现的功能集合和原生连接有少量不同。(自 v3.0.1 起)
|
||||
|
||||
连接方式的详细介绍请参考:[连接器建立连接的方式](../../develop/connect/#连接器建立连接的方式)
|
||||
|
||||
## 兼容性
|
||||
|
||||
:::warning
|
||||
* `TDengine.Connector` 3.1.0 版本进行了完整的重构,不再兼容 3.0.2 及以前版本。3.0.2 文档请参考 [nuget](https://www.nuget.org/packages/TDengine.Connector/3.0.2)
|
||||
* `TDengine.Connector` 3.x 不兼容 TDengine 2.x,如果在运行 TDengine 2.x 版本的环境下需要使用 C# 连接器请使用 TDengine.Connector 的 1.x 版本。
|
||||
:::
|
||||
|
||||
`TDengine.Connector` 的源码托管在 [GitHub](https://github.com/taosdata/taos-connector-dotnet/tree/3.0)。
|
||||
|
||||
## 支持的平台
|
||||
|
||||
|
@ -30,9 +33,12 @@ TDengine 不再支持 32 位 Windows 平台。
|
|||
|
||||
## 版本支持
|
||||
|
||||
| **Connector version** | **TDengine version** |
|
||||
|-----------------------|----------------------|
|
||||
| 3.1.0 | 3.2.1.0/3.1.1.18 |
|
||||
| **Connector 版本** | **TDengine 版本** | **主要功能** |
|
||||
|------------------|------------------|----------------------------|
|
||||
| 3.1.3 | 3.2.1.0/3.1.1.18 | 支持 WebSocket 自动重连 |
|
||||
| 3.1.2 | 3.2.1.0/3.1.1.18 | 修复 schemaless 资源释放 |
|
||||
| 3.1.1 | 3.2.1.0/3.1.1.18 | 支持 varbinary 和 geometry 类型 |
|
||||
| 3.1.0 | 3.2.1.0/3.1.1.18 | WebSocket 使用原生实现 |
|
||||
|
||||
## 处理异常
|
||||
|
||||
|
@ -57,6 +63,8 @@ TDengine 不再支持 32 位 Windows 平台。
|
|||
| BINARY | byte[] |
|
||||
| NCHAR | string (utf-8编码) |
|
||||
| JSON | byte[] |
|
||||
| VARBINARY | byte[] |
|
||||
| GEOMETRY | byte[] |
|
||||
|
||||
:::note
|
||||
JSON 类型仅在 tag 中支持。
|
||||
|
@ -68,7 +76,7 @@ JSON 类型仅在 tag 中支持。
|
|||
|
||||
* 安装 [.NET SDK](https://dotnet.microsoft.com/download)
|
||||
* [Nuget 客户端](https://docs.microsoft.com/en-us/nuget/install-nuget-client-tools) (可选安装)
|
||||
* 安装 TDengine 客户端驱动,具体步骤请参考[安装客户端驱动](../#安装客户端驱动)
|
||||
* 对于 Native 连接方式,需要安装 TDengine 客户端驱动,具体步骤请参考[安装客户端驱动](../#安装客户端驱动),WebSocket 连接方式无需安装。
|
||||
|
||||
### 安装连接器
|
||||
|
||||
|
@ -127,6 +135,11 @@ ConnectionStringBuilder 支持的参数如下:
|
|||
* connTimeout: WebSocket 连接超时时间,仅当 protocol 为 WebSocket 时有效,默认为 1 分钟,使用 `TimeSpan.Parse` 方法解析字符串为 `TimeSpan` 对象。
|
||||
* readTimeout: WebSocket 读超时时间,仅当 protocol 为 WebSocket 时有效,默认为 5 分钟,使用 `TimeSpan.Parse` 方法解析字符串为 `TimeSpan` 对象。
|
||||
* writeTimeout: WebSocket 写超时时间,仅当 protocol 为 WebSocket 时有效,默认为 10 秒,使用 `TimeSpan.Parse` 方法解析字符串为 `TimeSpan` 对象。
|
||||
* autoReconnect: 是否自动重连(连接器版本 3.1.3 及以上生效),默认为 false
|
||||
> **注意**:启用自动重连仅对简单执行 SQL 语句以及 无模式写入、数据订阅有效。对于参数绑定无效。自动重连仅对连接建立时通过参数指定数据库有效,对后面的 `use db` 语句切换数据库无效。
|
||||
|
||||
* reconnectRetryCount: 重连次数(连接器版本 3.1.3 及以上生效),默认为 3
|
||||
* reconnectIntervalMs: 重连间隔时间(连接器版本 3.1.3 及以上生效),默认为 2000
|
||||
|
||||
### 指定 URL 和 Properties 获取连接
|
||||
|
||||
|
@ -407,6 +420,8 @@ namespace WSQuery
|
|||
|
||||
### 执行带有 reqId 的 SQL
|
||||
|
||||
<RequestId />
|
||||
|
||||
<Tabs defaultValue="native" groupId="connect">
|
||||
<TabItem value="native" label="原生连接">
|
||||
|
||||
|
@ -801,6 +816,10 @@ consumer 支持的配置参数如下:
|
|||
* auto.commit.interval.ms: 自动提交 offset 的间隔时间,默认为 5000 毫秒
|
||||
* auto.offset.reset: 当 offset 不存在时,从哪里开始消费,可选值为 earliest 或 latest,默认为 latest
|
||||
* msg.with.table.name: 消息是否包含表名
|
||||
* ws.message.enableCompression: 是否启用 WebSocket 压缩(dotnet 版本 6 及以上,连接器版本 3.1.1 及以上生效),默认为 false
|
||||
* ws.autoReconnect: 是否自动重连(连接器版本 3.1.3 及以上生效),默认为 false
|
||||
* ws.reconnect.retry.count: 重连次数(连接器版本 3.1.3 及以上生效),默认为 3
|
||||
* ws.reconnect.interval.ms: 重连间隔时间(连接器版本 3.1.3 及以上生效),默认为 2000
|
||||
|
||||
|
||||
支持订阅结果集 `Dictionary<string, object>` key 为列名,value 为列值。
|
||||
|
|
|
@ -7,7 +7,7 @@ title: PHP Connector
|
|||
|
||||
PHP 连接器依赖 TDengine 客户端驱动。
|
||||
|
||||
项目地址:<https://github.com/Yurunsoft/php-tdengine>
|
||||
项目地址:\<https://github.com/Yurunsoft/php-tdengine>
|
||||
|
||||
TDengine 服务端或客户端安装后,`taos.h` 位于:
|
||||
|
||||
|
|
|
@ -14,6 +14,9 @@ TDengine ODBC 提供基于 WebSocket(推荐)和 原生连接两种方式连
|
|||
|
||||
想更多了解 TDengine 时序时序数据库的使用,可访问 [TDengine官方文档](https://docs.taosdata.com/intro/)。
|
||||
|
||||
## ODBC 版本兼容性
|
||||
- 支持 ODBC 3.8 及以前所有版本。
|
||||
|
||||
## 安装
|
||||
|
||||
1. 仅支持 Windows 平台。Windows 上需要安装过 VC 运行时库,可在此下载安装 [VC运行时库](https://learn.microsoft.com/en-us/cpp/windows/latest-supported-vc-redist?view=msvc-170) 如果已经安装VS开发工具可忽略。
|
||||
|
@ -48,17 +51,17 @@ TDengine ODBC 支持两种连接 TDengine 数据库方式:Websocket 连接与
|
|||
|
||||
4.1 【DSN】:Data Source Name 必填,为新添加的 ODBC 数据源命名
|
||||
|
||||
4.2【Connection Type】 : 必选,选择连接类型,这里选择 【Websocket】
|
||||
4.2【连接类型】 : 必选,选择连接类型,这里选择 【Websocket】
|
||||
|
||||
4.3【URL】必填,ODBC 数据源 URL,example: `http://localhost:6041`, 云服务的 url 示例: `https://gw.cloud.taosdata.com?token=your_token`
|
||||
4.3【URL】必填,ODBC 数据源 URL,示例: `http://localhost:6041`, 云服务的 url 示例: `https://gw.cloud.taosdata.com?token=your_token`
|
||||
|
||||
4.4【Database】选填,需要连接的默认数据库
|
||||
4.4【数据库】选填,需要连接的默认数据库
|
||||
|
||||
4.5【User】仅供第5步测试连接使用,选填,数据库用户名,如果不填,TDengine 默认 root
|
||||
4.5【用户名】仅供第5步测试连接使用,选填,数据库用户名,如果不填,TDengine 默认 root
|
||||
|
||||
4.6【Password】仅供第5步测试连接使用,选填,数据库用户密码,如果不填,TDengine 默认 taosdata
|
||||
4.6【密码】仅供第5步测试连接使用,选填,数据库用户密码,如果不填,TDengine 默认 taosdata
|
||||
|
||||
5. 点【Test Connecting...】测试连接情况,如果成功,提示"connecting success"
|
||||
5. 点【测试连接】测试连接情况,如果成功,提示"成功连接到URL"
|
||||
|
||||
6. 点【确定】,即可保存配置并退出
|
||||
|
||||
|
@ -78,17 +81,17 @@ TDengine ODBC 支持两种连接 TDengine 数据库方式:Websocket 连接与
|
|||
|
||||
4.1 【DSN】:Data Source Name 必填,为新添加的 ODBC 数据源命名
|
||||
|
||||
4.2 【Connection Type】 : 必选,选择连接类型,这里选择 【Native】 原生连接;
|
||||
4.2 【连接类型】 : 必选,选择连接类型,这里选择 【Native】 原生连接;
|
||||
|
||||
4.3 【Server】必填,ODBC 数据源 Server 地址,example: `localhost:6030`
|
||||
4.3 【服务器】必填,ODBC 数据源 服务器 地址,示例: `localhost:6030`
|
||||
|
||||
4.4 【Database】选填,需要连接的默认数据库
|
||||
4.4 【数据库】选填,需要连接的默认数据库
|
||||
|
||||
4.5 【User】仅供第5步测试连接使用,选填,数据库用户名,如果不填,TDengine 默认 root
|
||||
4.5 【用户名】仅供第5步测试连接使用,选填,数据库用户名,如果不填,TDengine 默认 root
|
||||
|
||||
4.6 【Password】仅供第5步测试连接使用,选填,数据库用户密码,如果不填,TDengine 默认 taosdata
|
||||
4.6 【密码】仅供第5步测试连接使用,选填,数据库用户密码,如果不填,TDengine 默认 taosdata
|
||||
|
||||
5. 点【Test Connecting...】测试连接情况,如果成功,提示"connecting success"
|
||||
5. 点【测试连接】测试连接情况,如果成功,提示"连接成功"
|
||||
|
||||
6. 点【确定】,即可保存配置并退出
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ TDengine 提供了兼容 InfluxDB (v1) 和 OpenTSDB 行协议的 Schemaless API
|
|||
- `precision` TDengine 使用的时间精度
|
||||
- `u` TDengine 用户名
|
||||
- `p` TDengine 密码
|
||||
- `ttl` 自动创建的子表生命周期,以子表的第一条数据的 TTL 参数为准,不可更新。更多信息请参考[创建表文档](taos-sql/table/#创建表)的 TTL 参数
|
||||
- `ttl` 自动创建的子表生命周期,以子表的第一条数据的 TTL 参数为准,不可更新。更多信息请参考[创建表文档](/../../taos-sql/table/#创建表)的 TTL 参数
|
||||
|
||||
注意: 目前不支持 InfluxDB 的 token 验证方式,仅支持 Basic 验证和查询参数验证。
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
:::info
|
||||
|
||||
由于 TDengine 的客户端驱动使用 C 语言编写,使用原生连接时需要加载系统对应安装在本地的客户端驱动共享库文件,通常包含在 TDengine 安装包。TDengine Linux 服务端安装包附带了 TDengine 客户端,也可以单独安装 [Linux 客户端](/get-started/) 。在 Windows 环境开发时需要安装 TDengine 对应的 [Windows 客户端](https://www.taosdata.com/cn/all-downloads/#TDengine-Windows-Client) 。
|
||||
由于 TDengine 的客户端驱动使用 C 语言编写,使用原生连接时需要加载系统对应安装在本地的客户端驱动共享库文件,通常包含在 TDengine 安装包。TDengine Linux 服务端安装包附带了 TDengine 客户端,也可以单独安装 [Linux 客户端](../get-started/) 。在 Windows 环境开发时需要安装 TDengine 对应的 [Windows 客户端](https://www.taosdata.com/cn/all-downloads/#TDengine-Windows-Client) 。
|
||||
|
||||
- libtaos.so: 在 Linux 系统中成功安装 TDengine 后,依赖的 Linux 版客户端驱动 libtaos.so 文件会被自动拷贝至 /usr/lib/libtaos.so,该目录包含在 Linux 自动扫描路径上,无需单独指定。
|
||||
- taos.dll: 在 Windows 系统中安装完客户端之后,依赖的 Windows 版客户端驱动 taos.dll 文件会自动拷贝到系统默认搜索路径 C:/Windows/System32 下,同样无需要单独指定。
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
reqId 可用于请求链路追踪,reqId 就像分布式系统中的 traceId 作用一样。一个请求可能需要经过多个服务或者模块才能完成。reqId 用于标识和关联这个请求的所有相关操作,以便于我们可以追踪和分析请求的完整路径。
|
||||
使用 reqId 有下面好处:
|
||||
- **请求追踪**:通过将同一个 reqId 关联到一个请求的所有相关操作,可以追踪请求在系统中的完整路径
|
||||
- **性能分析**:通过分析一个请求的 reqId,可以了解请求在各个服务和模块中的处理时间,从而找出性能瓶颈
|
||||
- **故障诊断**:当一个请求失败时,可以通过查看与该请求关联的 reqId 来找出问题发生的位置
|
||||
|
||||
如果用户不设置reqId,连接器也会内部随机生成一个,但是还是建议用户设置,可以更好的跟用户请求关联起来。
|
Before Width: | Height: | Size: 6.2 KiB After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 6.1 KiB After Width: | Height: | Size: 16 KiB |
|
@ -16,7 +16,9 @@ TDengine 提供了丰富的应用程序开发接口,为了便于用户快速
|
|||
| -------------- | --------- | -------- | ---------- | ------ | ----------- | ------ | -------- | ----- |
|
||||
| **X86 64bit** | **Linux** | ● | ● | ● | ● | ● | ● | ● |
|
||||
| **X86 64bit** | **Win64** | ● | ● | ● | ● | ● | ● | ● |
|
||||
| **X86 64bit** | **macOS** | ● | ● | ● | ○ | ○ | ● | ● |
|
||||
| **ARM64** | **Linux** | ● | ● | ● | ● | ○ | ○ | ● |
|
||||
| **ARM64** | **macOS** | ● | ● | ● | ○ | ○ | ● | ● |
|
||||
|
||||
其中 ● 表示官方测试验证通过,○ 表示非官方测试验证通过,-- 表示未经验证。
|
||||
|
||||
|
@ -54,14 +56,14 @@ TDengine 版本更新往往会增加新的功能特性,列表中的连接器
|
|||
|
||||
### 使用 http (REST 或 WebSocket) 接口
|
||||
|
||||
| **功能特性** | **Java** | **Python** | **Go** | **C# ** | **Node.js** | **Rust** |
|
||||
| ------------------------------ | -------- | ---------- | -------- | -------- | ----------- | -------- |
|
||||
| **连接管理** | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 |
|
||||
| **普通查询** | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 |
|
||||
| **参数绑定** | 支持 | 支持 | 支持 | 支持 | 暂不支持 | 支持 |
|
||||
| **数据订阅(TMQ)** | 支持 | 支持 | 支持 | 暂不支持 | 暂不支持 | 支持 |
|
||||
| **Schemaless** | 支持 | 支持 | 支持 | 暂不支持 | 暂不支持 | 支持 |
|
||||
| **批量拉取(基于 WebSocket)** | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 |
|
||||
| **功能特性** | **Java** | **Python** | **Go** | **C# ** | **Node.js** | **Rust** |
|
||||
| ------------------------------ | -------- | ---------- | -------- | ---- | ----------- | -------- |
|
||||
| **连接管理** | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 |
|
||||
| **普通查询** | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 |
|
||||
| **参数绑定** | 支持 | 支持 | 支持 | 支持 | 暂不支持 | 支持 |
|
||||
| **数据订阅(TMQ)** | 支持 | 支持 | 支持 | 支持 | 暂不支持 | 支持 |
|
||||
| **Schemaless** | 支持 | 支持 | 支持 | 支持 | 暂不支持 | 支持 |
|
||||
| **批量拉取(基于 WebSocket)** | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 |
|
||||
|
||||
:::warning
|
||||
|
||||
|
|
|
@ -171,17 +171,11 @@ Query OK, 8 row(s) in set (0.001154s)
|
|||
|
||||
启动 CLI 程序 taos,执行:
|
||||
|
||||
```sql
|
||||
DROP DNODE "fqdn:port";
|
||||
```
|
||||
|
||||
或者
|
||||
|
||||
```sql
|
||||
DROP DNODE dnodeId;
|
||||
```
|
||||
|
||||
通过 “fqdn:port” 或 dnodeID 来指定一个具体的节点都是可以的。其中 fqdn 是被删除的节点的 FQDN,port 是其对外服务器的端口号;dnodeID 可以通过 SHOW DNODES 获得。
|
||||
dnodeId 可以通过 SHOW DNODES 获得。
|
||||
|
||||
:::warning
|
||||
|
||||
|
|
|
@ -299,7 +299,7 @@ Query OK, 8 row(s) in set (0.001488s)
|
|||
|
||||
#### 手工创建
|
||||
|
||||
常见一个三副本的 test1,并创建一张表,写入 2 条数据
|
||||
创建一个三副本的test1,并创建一张表,写入2条数据
|
||||
|
||||
```Bash
|
||||
kubectl exec -it tdengine-0 -n tdengine-test -- \
|
||||
|
@ -310,7 +310,7 @@ kubectl exec -it tdengine-0 -n tdengine-test -- \
|
|||
insert into t1 values(now, 1)(now+1s, 2);"
|
||||
```
|
||||
|
||||
通过 show test1.vgroup 查看 xnode 分布情况
|
||||
通过show test1.vgroup 查看vnode分布情况
|
||||
|
||||
```Bash
|
||||
kubectl exec -it tdengine-0 -n tdengine-test -- taos -s "show test1.vgroups"
|
||||
|
|