TDengine Python 连接器 — taospy 与 taos-ws-py 完整指南

分类 :11.客户端与连接器 | 篇章 :04 Python 连接器

详情

TDengine 提供 taospy(Native)和 taos-ws-py(WebSocket)两个 Python 包,均实现 PEP 249 DB-API 规范。本文涵盖安装、基本用法、STMT2、Schemaless、订阅、Pandas/SQLAlchemy 集成。

包速查表

协议 端口 依赖
taospy Native 6030 libtaos
taos-ws-py WebSocket 6041
taospy (RestClient) REST 6041

详细解析

1. 安装

bash 复制代码
# Native (需要 libtaos)
pip install taospy

# WebSocket (推荐)
pip install taos-ws-py

# 两个都装(按需选用)
pip install taospy taos-ws-py

2. 基本用法

python 复制代码
# Native
import taos
conn = taos.connect(
    host="localhost",
    port=6030,
    user="root",
    password="taosdata",
    database="test"
)

# WebSocket
import taosws
conn = taosws.connect("taosws://root:taosdata@localhost:6041/test")


# 查询
cursor = conn.cursor()
cursor.execute("CREATE DATABASE IF NOT EXISTS test")
cursor.execute("USE test")

cursor.execute("""
  CREATE STABLE IF NOT EXISTS meters (
    ts TIMESTAMP, current FLOAT, voltage INT
  ) TAGS (location VARCHAR(32))
""")

# 插入
cursor.execute("""
  INSERT INTO d001 USING meters TAGS('Beijing') 
  VALUES (NOW, 25.3, 220)
""")

# 查询
cursor.execute("SELECT * FROM meters LIMIT 10")
for row in cursor:
    print(row)

cursor.close()
conn.close()

3. 参数化查询

python 复制代码
# 标准 DB-API
cursor.execute(
    "SELECT * FROM meters WHERE ts > ? AND current > ?",
    (datetime.now() - timedelta(hours=1), 100)
)

# 批量插入
cursor.executemany(
    "INSERT INTO d001 VALUES (?, ?, ?)",
    [(ts1, 25.0, 220), (ts2, 26.0, 221), ...]
)

4. STMT2 高性能写入

python 复制代码
# WebSocket STMT2
import taosws

conn = taosws.connect("taosws://root:taosdata@localhost:6041/test")

stmt = conn.statement2(
    "INSERT INTO ? USING meters TAGS(?) VALUES(?, ?, ?)"
)

# 准备多个子表的数据
table_names = ["d001", "d002"]
tags = [["Beijing"], ["Shanghai"]]
cols = [
    [
        [int(time.time()*1000), int(time.time()*1000)+1000],  # ts
        [25.3, 26.1],                                          # current
        [220, 221]                                             # voltage
    ],
    [
        [int(time.time()*1000), int(time.time()*1000)+1000],
        [27.5, 28.2],
        [218, 219]
    ]
]

stmt.bind_param(table_names, tags, cols)
stmt.execute()
stmt.close()

5. Schemaless 写入

python 复制代码
import taos
from taos import SmlProtocol, SmlPrecision

conn = taos.connect(host="localhost", database="test")

# InfluxDB Line
lines = [
    "meters,location=Beijing current=25.3,voltage=220i 1717488000000",
    "meters,location=Shanghai current=26.1,voltage=219i 1717488001000"
]
conn.schemaless_insert(
    lines, 
    SmlProtocol.LINE_PROTOCOL,
    SmlPrecision.MILLI_SECONDS
)


# OpenTSDB JSON
import json
data = [{
    "metric": "meters.current",
    "timestamp": 1717488000,
    "value": 25.3,
    "tags": {"location": "Beijing"}
}]
conn.schemaless_insert(
    [json.dumps(data)],
    SmlProtocol.JSON_PROTOCOL,
    SmlPrecision.SECONDS
)

6. TMQ 订阅

python 复制代码
from taos.tmq import Consumer

consumer = Consumer({
    "td.connect.ip": "localhost",
    "td.connect.user": "root",
    "td.connect.pass": "taosdata",
    "group.id": "my_group",
    "auto.offset.reset": "earliest",
    "enable.auto.commit": "true"
})

consumer.subscribe(["my_topic"])

try:
    while True:
        msg = consumer.poll(1)  # 1 秒超时
        if msg is None:
            continue
        
        for block in msg:
            for row in block:
                print(row)
        
        consumer.commit()
except KeyboardInterrupt:
    pass
finally:
    consumer.close()


# WebSocket 版本
from taosws import TmqConsumer
consumer = TmqConsumer(
    "taosws://root:taosdata@localhost:6041/",
    group_id="my_group",
    auto_offset_reset="earliest"
)
consumer.subscribe(["my_topic"])

7. Pandas 集成

python 复制代码
import pandas as pd
import taosws

conn = taosws.connect("taosws://root:taosdata@localhost:6041/test")

# 查询 → DataFrame
df = pd.read_sql(
    "SELECT _wstart, AVG(current) AS avg_c FROM meters "
    "WHERE ts > NOW - 1d INTERVAL(1h)",
    conn
)

print(df.head())

# 处理
df.set_index('_wstart', inplace=True)
df.plot(figsize=(12, 4))


# DataFrame → 写入
df_to_insert = pd.DataFrame({
    'ts': pd.date_range('2026-06-04', periods=1000, freq='S'),
    'current': np.random.rand(1000) * 30,
    'voltage': np.random.randint(218, 223, 1000)
})

cursor = conn.cursor()
for _, row in df_to_insert.iterrows():
    cursor.execute(
        f"INSERT INTO d001 VALUES ('{row.ts}', {row.current}, {row.voltage})"
    )

8. SQLAlchemy 集成

python 复制代码
from sqlalchemy import create_engine, text

# Native
engine = create_engine("taos://root:taosdata@localhost:6030/test")

# WebSocket
engine = create_engine("taosws://root:taosdata@localhost:6041/test")

# REST
engine = create_engine("taosrest://root:taosdata@localhost:6041/test")


with engine.connect() as conn:
    result = conn.execute(text("SELECT * FROM meters LIMIT 10"))
    for row in result:
        print(row)


# Pandas + SQLAlchemy
df = pd.read_sql("SELECT * FROM meters LIMIT 100", engine)

代码示例

完整数据采集脚本

python 复制代码
import time
import random
import taosws
from datetime import datetime

def main():
    conn = taosws.connect(
        "taosws://root:taosdata@localhost:6041/iot")
    cursor = conn.cursor()
    
    # 准备 schema
    cursor.execute("""
      CREATE DATABASE IF NOT EXISTS iot
    """)
    cursor.execute("""
      CREATE STABLE IF NOT EXISTS sensors (
        ts TIMESTAMP, temp FLOAT, humidity FLOAT
      ) TAGS (device_id VARCHAR(32), location VARCHAR(32))
    """)
    
    # 模拟采集
    devices = [
        ("d001", "Floor1"),
        ("d002", "Floor1"),
        ("d003", "Floor2"),
    ]
    
    while True:
        ts = int(time.time() * 1000)
        for dev_id, loc in devices:
            temp = 20 + random.random() * 10
            humidity = 40 + random.random() * 30
            
            cursor.execute(
                f"INSERT INTO {dev_id} USING sensors "
                f"TAGS('{dev_id}', '{loc}') "
                f"VALUES ({ts}, {temp:.2f}, {humidity:.2f})"
            )
        
        time.sleep(1)

if __name__ == "__main__":
    main()

数据分析

python 复制代码
import taosws
import pandas as pd
import matplotlib.pyplot as plt

conn = taosws.connect("taosws://root:taosdata@localhost:6041/iot")

# 小时聚合
df = pd.read_sql("""
  SELECT _wstart, location, AVG(temp) AS avg_temp 
  FROM sensors 
  WHERE ts > NOW - 1d 
  PARTITION BY location 
  INTERVAL(1h)
""", conn)

# 数据透视
pivot = df.pivot(index='_wstart', columns='location', values='avg_temp')
pivot.plot(figsize=(12, 6))
plt.title("Hourly Temperature by Location")
plt.savefig("temp_trend.png")

性能考量

Python 连接器性能

操作 吞吐
cursor.execute() 单条 几千行/秒
executemany 批量 几万行/秒
Schemaless 几十万行/秒
STMT2 列绑定 上百万行/秒

优化建议

措施 效果
用 STMT2 5~10x 提升
大批量绑定 显著提升
asyncio 异步 并发提升
Pandas to_sql 简洁但通常慢

FAQ

Q1: taospy vs taos-ws-py 怎么选?

  • 本地开发:taos-ws-py(无 libtaos 依赖)
  • 容器化部署:taos-ws-py
  • 极致性能:taospy
  • 浏览器场景:taos-ws-py

Q2: 安装 taospy 报错找不到 libtaos?

需先安装 TDengine 客户端:

bash 复制代码
# 下载 taosTools
wget ... && tar xzf ...
sudo ./install.sh -e no

Q3: 异步支持?

taos-ws-py 提供异步接口:

python 复制代码
import taosws
async def query():
    conn = await taosws.connect_async("...")
    cursor = await conn.cursor_async()
    await cursor.execute("SELECT ...")

Q4: 时间戳类型?

返回 datetime(Native)或 int(WS,毫秒)。注意类型差异。

Q5: 中文乱码?

数据库 PRECISION 与 LOCALE 设置正确:

python 复制代码
conn = taos.connect(..., config="/etc/taos")
# taos.cfg 中设 locale en_US.UTF-8

参考

系统构架篇

数据模型

存储引擎

查询引擎

数据写入

数据订阅

预聚合

索引

SQL 语句

客户端与连接器

关于 TDengine

TDengine 专为物联网IoT平台、工业大数据平台设计。其中,TDengine TSDB 是一款高性能、分布式的时序数据库(Time Series Database),同时它还带有内建的缓存、流式计算、数据订阅等系统功能;TDengine IDMP 是一款AI原生工业数据管理平台,它通过树状层次结构建立数据目录,对数据进行标准化、情景化,并通过 AI 提供实时分析、可视化、事件管理与报警等功能。

相关推荐
丁丁点灯o11 分钟前
Oracle中使用外键的场景及不适用外键的情况
数据库·oracle
天天进步201517 分钟前
Pixelle-Video 源码解析 #18:声音克隆功能:参考音频如何影响解说效果?
数据库·音视频
znnnk19 分钟前
【Python】GUI 开发从入门到实战(三):PyQt/PySide 进阶之路
开发语言·python·pyqt
合米AI SOP系统30 分钟前
传统产线如何快速上马落地 AI 防错?合米科技 AI SOP 7天即可上线。
大数据·人工智能·科技
思录Echo31 分钟前
什么决定具身智能的最终走向?多技术路线与落地现实辨析
大数据·人工智能
不懂的浪漫1 小时前
ToDesk 连接 Linux 后分辨率过低的解决方法
linux·运维·数据库
xiaohaiAIgeo1 小时前
【2026年】AI监控加行为分析守护实验室安全
大数据·人工智能·科普知识
布莱克6051 小时前
Redis 详解:从核心数据结构到高可用架构
数据库
林墨聊AIGC2 小时前
动漫AI视频创作工具在哪找到的?2026年最新动漫AI视频平台与软件指南
大数据·人工智能·ai作画·aigc·音视频
冰暮流星2 小时前
mysql之左外连接与右外连接
数据库·sql