提交 9cd7bb62 编写于 作者: D dingbo

docs: python

上级 79ddaa72
...@@ -77,7 +77,7 @@ To obtain the value of cloud token and URL, please log in [TDengine Cloud](https ...@@ -77,7 +77,7 @@ To obtain the value of cloud token and URL, please log in [TDengine Cloud](https
Copy code bellow to your editor and run it. Copy code bellow to your editor and run it.
```python ```python
{{#include docs/examples/python/connect_cloud_example.py:connect}} {{#include docs/examples/python/develop_tutorial.py:connect}}
``` ```
The client connection is then established. For how to write data and query data, please refer to [sample-program](https://docs.tdengine.com/cloud/connector/python/#sample-program). The client connection is then established. For how to write data and query data, please refer to [sample-program](https://docs.tdengine.com/cloud/connector/python/#sample-program).
# Insert Data # Insert Data
## Introduction import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
Application programs can execute `INSERT` statement through connectors to insert rows. The TAOS CLI can also be used to manually insert data. ## SQL Examples
Here are some brief examples for `INSET` statement. You can execute these statements manually by TDengine CLI or TDengine Cloud Explorer or programmatically by TDengine connectors.
### Insert Single Row ### Insert Single Row
...@@ -30,16 +33,24 @@ INSERT INTO d1001 VALUES (1538548685000, 10.3, 219, 0.31) (1538548695000, 12.6, ...@@ -30,16 +33,24 @@ INSERT INTO d1001 VALUES (1538548685000, 10.3, 219, 0.31) (1538548695000, 12.6,
For more details about `INSERT` please refer to [INSERT](/taos-sql/insert). For more details about `INSERT` please refer to [INSERT](/taos-sql/insert).
:::info
- Inserting in batches can improve performance. Normally, the higher the batch size, the better the performance. Please note that a single row can't exceed 48K bytes and each SQL statement can't exceed 1MB.
- Inserting with multiple threads can also improve performance. However, depending on the system resources on the application side and the server side, when the number of inserting threads grows beyond a specific point the performance may drop instead of improving. The proper number of threads needs to be tested in a specific environment to find the best number.
::: ## Connector Examples
:::warning <Tabs>
<TabItem value="python" label="Python">
- If the timestamp for the row to be inserted already exists in the table, the behavior depends on the value of parameter `UPDATE`. If it's set to 0 (the default value), the row will be discarded. If it's set to 1, the new values will override the old values for the same row. In this example, we use `execute` method to execute SQL and get affected rows. The variable `conn` is an instance of class `taosrest.TaosRestConnection` we just created at [Connect Tutorial](./connect/python#connect).
- The timestamp to be inserted must be newer than the timestamp of subtracting current time by the parameter `KEEP`. If `KEEP` is set to 3650 days, then the data older than 3650 days ago can't be inserted. The timestamp to be inserted can't be newer than the timestamp of current time plus parameter `DAYS`. If `DAYS` is set to 2, the data newer than 2 days later can't be inserted.
::: ```python
\ No newline at end of file {{#include docs/examples/python/develop_tutorial.py:insert}}
```
</TabItem>
<TabItem value="java" label="Java">
</TabItem>
<TabItem value="go" label="Go">
</TabItem>
<TabItem value="rust" label="Rust">
</TabItem>
<TabItem value="node" label="Node.js">
</TabItem>
</Tabs>
# Query Data # Query Data
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
## Introduction ## Query Using SQL
SQL is used by TDengine as its query language. Application programs can send SQL statements to TDengine through REST API or connectors. TDengine's CLI `taos` can also be used to execute ad hoc SQL queries. Here is the list of major query functionalities supported by TDengine: SQL is used by TDengine as its query language. Application programs can send SQL statements to TDengine through REST API or connectors. TDengine's CLI `taos` can also be used to execute ad hoc SQL queries. Here is the list of major query functionalities supported by TDengine:
...@@ -113,3 +115,42 @@ Interpolation can be performed in TDengine if there is no data in a time range. ...@@ -113,3 +115,42 @@ Interpolation can be performed in TDengine if there is no data in a time range.
For more details please refer to [Aggregate by Window](/taos-sql/interval). For more details please refer to [Aggregate by Window](/taos-sql/interval).
## Connector Examples
<Tabs>
<TabItem value="python" label="Python">
In this example, we use `query` method to execute SQL and get a `result` object.
```python
{{#include docs/examples/python/develop_tutorial.py:query:nrc}}
```
Get column metadata(column name, column type and column length) from `result`:
```python
{{#include docs/examples/python/develop_tutorial.py:fields:nrc}}
```
Get total rows from `result`:
```python
{{#include docs/examples/python/develop_tutorial.py:rows:nrc}}
```
Iterate over each rows:
```python
{{#include docs/examples/python/develop_tutorial.py:iter}}
```
</TabItem>
<TabItem value="java" label="Java">
</TabItem>
<TabItem value="go" label="Go">
</TabItem>
<TabItem value="rust" label="Rust">
</TabItem>
<TabItem value="node" label="Node.js">
</TabItem>
</Tabs>
\ No newline at end of file
...@@ -3,7 +3,6 @@ sidebar_label: Python ...@@ -3,7 +3,6 @@ sidebar_label: Python
title: TDengine Python Connector title: TDengine Python Connector
--- ---
`taospy` is the official Python connector for TDengine. `taospy` wraps the [REST interface](/reference/rest-api) of TDengine. Additionally `taospy` 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/). `taospy` is the official Python connector for TDengine. `taospy` wraps the [REST interface](/reference/rest-api) of TDengine. Additionally `taospy` 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/).
The source code for the Python connector is hosted on [GitHub](https://github.com/taosdata/taos-connector-python). The source code for the Python connector is hosted on [GitHub](https://github.com/taosdata/taos-connector-python).
...@@ -18,7 +17,12 @@ The source code for the Python connector is hosted on [GitHub](https://github.co ...@@ -18,7 +17,12 @@ The source code for the Python connector is hosted on [GitHub](https://github.co
### Install via pip ### Install via pip
``` ```
pip3 install taospy>=2.3.3 pip3 install -U taospy
```
### Install vial conda
```
conda install -c conda-forge taospy
``` ```
### Installation verification ### Installation verification
...@@ -32,7 +36,7 @@ import taosrest ...@@ -32,7 +36,7 @@ import taosrest
## Establish connection ## Establish connection
```python ```python
{{#include docs/examples/python/connect_cloud_example.py:connect}} {{#include docs/examples/python/reference_connection.py:connect}}
``` ```
All arguments to the `connect()` function are optional keyword arguments. The following are the connection parameters specified. All arguments to the `connect()` function are optional keyword arguments. The following are the connection parameters specified.
...@@ -43,12 +47,18 @@ All arguments to the `connect()` function are optional keyword arguments. The fo ...@@ -43,12 +47,18 @@ All arguments to the `connect()` function are optional keyword arguments. The fo
## Sample program ## Sample program
### Use of TaosRestCursor class ### Use of TaosRestConnection Class
```python
{{#include docs/examples/python/reference_connection.py:example}}
```
### Use of TaosRestCursor Class
The ``TaosRestCursor`` class is an implementation of the PEP249 Cursor interface. The `TaosRestCursor` class is an implementation of the PEP249 Cursor interface.
```python title="Use of TaosRestCursor" ```python
{{#include docs/examples/python/connect_cloud_example.py:basic}} {{#include docs/examples/python/reference_cursor.py:basic}}
``` ```
- `cursor.execute` : Used to execute arbitrary SQL statements. - `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.rowcount` : For write operations, returns the number of successful rows written. For query operations, returns the number of rows in the result set.
...@@ -58,8 +68,8 @@ The ``TaosRestCursor`` class is an implementation of the PEP249 Cursor interface ...@@ -58,8 +68,8 @@ The ``TaosRestCursor`` class is an implementation of the PEP249 Cursor interface
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. 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" ```python
{{#include docs/examples/python/rest_client_cloud_example.py}} {{#include docs/examples/python/reference_rest_client.py}}
``` ```
For a more detailed description of the `sql()` method, please refer to [RestClient](https://docs.taosdata.com/api/taospy/taosrest/restclient.html). For a more detailed description of the `sql()` method, please refer to [RestClient](https://docs.taosdata.com/api/taospy/taosrest/restclient.html).
......
.vscode .vscode
*.lock *.lock
.idea .idea
.env .env
\ No newline at end of file *.un~
*~
.vim
\ No newline at end of file
import pandas
from sqlalchemy import create_engine
engine = create_engine("taosrest://root:taosdata@localhost:6041")
df: pandas.DataFrame = pandas.read_sql("SELECT * FROM power.meters", engine)
# print index
print(df.index)
# print data type of element in ts column
print(type(df.ts[0]))
print(df.head(3))
# output:
# RangeIndex(start=0, stop=8, step=1)
# <class 'pandas._libs.tslibs.timestamps.Timestamp'>
# ts current ... location groupid
# 0 2018-10-03 06:38:05.500000+00:00 11.8 ... california.losangeles 2
# 1 2018-10-03 06:38:16.600000+00:00 13.4 ... california.losangeles 2
# 2 2018-10-03 06:38:05+00:00 10.8 ... california.losangeles 3
# ANCHOR: connect
from taosrest import connect, TaosRestConnection, TaosRestCursor
conn: TaosRestConnection = connect(url="http://localhost:6041",
user="root",
password="taosdata",
timeout=30)
# ANCHOR_END: connect
# ANCHOR: basic
# create STable
cursor: TaosRestCursor = conn.cursor()
cursor.execute("DROP DATABASE IF EXISTS power")
cursor.execute("CREATE DATABASE power")
cursor.execute("CREATE STABLE power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (location BINARY(64), groupId INT)")
# insert data
cursor.execute("""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)""")
print("inserted row count:", cursor.rowcount)
# query data
cursor.execute("SELECT * FROM power.meters LIMIT 3")
# get total rows
print("queried row count:", cursor.rowcount)
# get column names from cursor
column_names = [meta[0] for meta in cursor.description]
# get rows
data: list[tuple] = cursor.fetchall()
print(column_names)
for row in data:
print(row)
# output:
# inserted row count: 8
# queried row count: 3
# ['ts', 'current', 'voltage', 'phase', 'location', 'groupid']
# [datetime.datetime(2018, 10, 3, 14, 38, 5, 500000, tzinfo=datetime.timezone(datetime.timedelta(seconds=28800), '+08:00')), 11.8, 221, 0.28, 'california.losangeles', 2]
# [datetime.datetime(2018, 10, 3, 14, 38, 16, 600000, tzinfo=datetime.timezone(datetime.timedelta(seconds=28800), '+08:00')), 13.4, 223, 0.29, 'california.losangeles', 2]
# [datetime.datetime(2018, 10, 3, 14, 38, 5, tzinfo=datetime.timezone(datetime.timedelta(seconds=28800), '+08:00')), 10.8, 223, 0.29, 'california.losangeles', 3]
# ANCHOR_END: basic
from dotenv import load_dotenv
# read .env file from current working directory
load_dotenv()
# ANCHOR: connect
import taosrest
import os
url = os.environ["TDENGINE_CLOUD_URL"]
token = os.environ["TDENGINE_CLOUD_TOKEN"]
conn = taosrest.connect(url=url, token=token)
# test the connection by getting version info
print("server version:", conn.server_info)
# ANCHOR_END: connect
# ANCHOR: insert
# drop database
affected_row = conn.execute("DROP DATABASE IF EXISTS power")
print("affected_row", affected_row) # 0
# create database
affected_row = conn.execute("CREATE DATABASE power")
print("affected_row", affected_row) # 0
# create super table
conn.execute("CREATE STABLE power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (location BINARY(64), groupId INT)")
print("affected_row", affected_row) # 0
# insert multiple rows into multiple tables at once. subtables will be created automatically.
affected_row = conn.execute("""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)
""")
print("affected_row", affected_row) # 4
# ANCHOR_END: insert
# ANCHOR: query
result = conn.query("SELECT ts, current FROM power.meters LIMIT 2")
# ANCHOR_END: query
# ANCHOR: fields
print(result.fields)
# output: [{'name': 'ts', 'type': 9, 'bytes': 8}, {'name': 'current', 'type': 6, 'bytes': 4}]
# ANCHOR_END: fields
# ANCHOR: rows
print(result.rows)
# output: 3
# ANCHOR_END: rows
# ANCHOR: iter
for row in result:
print(row)
# output:
# [datetime.datetime(2018, 10, 3, 14, 38, 5, tzinfo=datetime.timezone.utc), 10.3]
# [datetime.datetime(2018, 10, 3, 14, 38, 15, tzinfo=datetime.timezone.utc), 12.6]
import json
import taos
from taos import SmlProtocol, SmlPrecision
lines = [{"metric": "meters.current", "timestamp": 1648432611249, "value": 10.3, "tags": {"location": "California.SanFrancisco", "groupid": 2}},
{"metric": "meters.voltage", "timestamp": 1648432611249, "value": 219,
"tags": {"location": "California.LosAngeles", "groupid": 1}},
{"metric": "meters.current", "timestamp": 1648432611250, "value": 12.6,
"tags": {"location": "California.SanFrancisco", "groupid": 2}},
{"metric": "meters.voltage", "timestamp": 1648432611250, "value": 221, "tags": {"location": "California.LosAngeles", "groupid": 1}}]
def get_connection():
return taos.connect()
def create_database(conn):
conn.execute("CREATE DATABASE test")
conn.execute("USE test")
def insert_lines(conn):
global lines
lines = json.dumps(lines)
# note: the first parameter must be a list with only one element.
affected_rows = conn.schemaless_insert(
[lines], SmlProtocol.JSON_PROTOCOL, SmlPrecision.NOT_CONFIGURED)
print(affected_rows) # 4
if __name__ == '__main__':
connection = get_connection()
try:
create_database(connection)
insert_lines(connection)
finally:
connection.close()
import taos
from taos import SmlProtocol, SmlPrecision
lines = ["meters,location=California.LosAngeles,groupid=2 current=11.8,voltage=221,phase=0.28 1648432611249000",
"meters,location=California.LosAngeles,groupid=2 current=13.4,voltage=223,phase=0.29 1648432611249500",
"meters,location=California.LosAngeles,groupid=3 current=10.8,voltage=223,phase=0.29 1648432611249300",
"meters,location=California.LosAngeles,groupid=3 current=11.3,voltage=221,phase=0.35 1648432611249800",
]
def get_connection():
# create connection use firstEP in taos.cfg.
return taos.connect()
def create_database(conn):
# the default precision is ms (microsecond), but we use us(microsecond) here.
conn.execute("CREATE DATABASE test precision 'us'")
conn.execute("USE test")
def insert_lines(conn):
affected_rows = conn.schemaless_insert(
lines, SmlProtocol.LINE_PROTOCOL, SmlPrecision.MICRO_SECONDS)
print(affected_rows) # 8
if __name__ == '__main__':
connection = get_connection()
try:
create_database(connection)
insert_lines(connection)
finally:
connection.close()
import taos
from datetime import datetime
# ANCHOR: bind_batch
table_tags = {
"d1001": ('California.SanFrancisco', 2),
"d1002": ('California.SanFrancisco', 3),
"d1003": ('California.LosAngeles', 2),
"d1004": ('California.LosAngeles', 3)
}
table_values = {
"d1001": [
['2018-10-03 14:38:05.000', '2018-10-03 14:38:15.000', '2018-10-03 14:38:16.800'],
[10.3, 12.6, 12.3],
[219, 218, 221],
[0.31, 0.33, 0.32]
],
"d1002": [
['2018-10-03 14:38:16.650'], [10.3], [218], [0.25]
],
"d1003": [
['2018-10-03 14:38:05.500', '2018-10-03 14:38:16.600'],
[11.8, 13.4],
[221, 223],
[0.28, 0.29]
],
"d1004": [
['2018-10-03 14:38:05.500', '2018-10-03 14:38:06.500'],
[10.8, 11.5],
[223, 221],
[0.29, 0.35]
]
}
def bind_multi_rows(stmt: taos.TaosStmt):
"""
batch bind example
"""
for tb_name in table_values.keys():
tags = table_tags[tb_name]
tag_params = taos.new_bind_params(2)
tag_params[0].binary(tags[0])
tag_params[1].int(tags[1])
stmt.set_tbname_tags(tb_name, tag_params)
values = table_values[tb_name]
value_params = taos.new_multi_binds(4)
value_params[0].timestamp([get_ts(t) for t in values[0]])
value_params[1].float(values[1])
value_params[2].int(values[2])
value_params[3].float(values[3])
stmt.bind_param_batch(value_params)
def insert_data():
conn = taos.connect(database="power")
try:
stmt = conn.statement("INSERT INTO ? USING meters TAGS(?, ?) VALUES(?, ?, ?, ?)")
bind_multi_rows(stmt)
stmt.execute()
stmt.close()
finally:
conn.close()
# ANCHOR_END: bind_batch
def create_stable():
conn = taos.connect()
try:
conn.execute("CREATE DATABASE power")
conn.execute("CREATE STABLE power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) "
"TAGS (location BINARY(64), groupId INT)")
finally:
conn.close()
def get_ts(ts: str):
dt = datetime.strptime(ts, '%Y-%m-%d %H:%M:%S.%f')
return int(dt.timestamp() * 1000)
if __name__ == '__main__':
create_stable()
insert_data()
from dotenv import load_dotenv
# read .env file from current working directory
load_dotenv()
# ANCHOR: connect
import taosrest
import os
url = os.environ["TDENGINE_CLOUD_URL"]
token = os.environ["TDENGINE_CLOUD_TOKEN"]
conn = taosrest.connect(url=url, token=token)
# test the connection by getting version info
print("server version:", conn.server_info)
# ANCHOR_END: connect
# ANCHOR: example
affected_row = conn.execute("DROP DATABASE IF EXISTS power")
print("affected_row", affected_row) # 0
affected_row = conn.execute("CREATE DATABASE power")
print("affected_row", affected_row) # 0
conn.execute("CREATE STABLE power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (location BINARY(64), groupId INT)")
print("affected_row", affected_row) # 0
affected_row = conn.execute("""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)
""")
print("affected_row", affected_row) # 8
result = conn.query("SELECT ts, current FROM power.meters LIMIT 2")
print("metadata of each column:\n", result.fields) # [{'name': 'ts', 'type': 9, 'bytes': 8}, {'name': 'current', 'type': 6, 'bytes': 4}]
print("total rows:", result.rows) # 2
# Iterate over result.
for row in result:
print(row)
# output:
# [datetime.datetime(2018, 10, 3, 14, 38, 5, tzinfo=datetime.timezone.utc), 10.3]
# [datetime.datetime(2018, 10, 3, 14, 38, 15, tzinfo=datetime.timezone.utc), 12.6]
# Or get all rows as a list
print(result.data) # [[datetime.datetime(2018, 10, 3, 14, 38, 5, tzinfo=datetime.timezone.utc), 10.3], [datetime.datetime(2018, 10, 3, 14, 38, 15, tzinfo=datetime.timezone.utc), 12.6]]
# ANCHOR_END: example
import taos
from taos import SmlProtocol, SmlPrecision
# format: <metric> <timestamp> <value> <tagk_1>=<tagv_1>[ <tagk_n>=<tagv_n>]
lines = ["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",
]
# create connection use firstEp in taos.cfg.
def get_connection():
return taos.connect()
def create_database(conn):
conn.execute("CREATE DATABASE test")
conn.execute("USE test")
def insert_lines(conn):
affected_rows = conn.schemaless_insert(
lines, SmlProtocol.TELNET_PROTOCOL, SmlPrecision.NOT_CONFIGURED)
print(affected_rows) # 8
if __name__ == '__main__':
connection = get_connection()
try:
create_database(connection)
insert_lines(connection)
finally:
connection.close()
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册