You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iotdb.apache.org by ji...@apache.org on 2019/10/10 07:50:27 UTC
[incubator-iotdb] 01/01: add python client example in user guide
This is an automated email from the ASF dual-hosted git repository.
jiangtian pushed a commit to branch add_python_cli_in_guide
in repository https://gitbox.apache.org/repos/asf/incubator-iotdb.git
commit 037057eda4e1816d059601fd75342c6a73975c34
Author: jt <jt...@163.com>
AuthorDate: Thu Oct 10 15:38:24 2019 +0800
add python client example in user guide
---
client-py/readme.md | 28 ++--
docs/Documentation-CHN/OtherMaterial-Examples.md | 160 ++++++++++++++++++++++
docs/Documentation/OtherMaterial-Examples.md | 164 +++++++++++++++++++++++
3 files changed, 342 insertions(+), 10 deletions(-)
diff --git a/client-py/readme.md b/client-py/readme.md
index 8b79c94..9d849db 100644
--- a/client-py/readme.md
+++ b/client-py/readme.md
@@ -19,24 +19,32 @@
-->
-# introduction
-This is an example of how to connect to IoTDB with python, using the thrift rpc interfaces. Things will be a bit different
-on Linux or Windows, we will introduce how to operate on the two systems separately.
+# Python connection
+## introduction
+This is an example of how to connect to IoTDB with python, using the thrift rpc interfaces. Things
+are almost the same on Windows or Linux, but pay attention to the difference like path separator.
## Prerequisites
python3.7 or later is preferred.
You have to install Thrift (0.11.0 or later) to compile our thrift file into python code. Below is the official
-tutorial of installation:
+tutorial of installation, eventually, you should have a thrift executable.
```
http://thrift.apache.org/docs/install/
```
-## Compile
-If you have added Thrift executable into your path, you may just run `compile.sh` or `compile.bat`, or you will have to
-modify it to set variable `THRIFT_EXE` to point to your executable. This will generate thrift sources under folder `target`,
-you can add it to your `PYTHONPATH` so that you would be able to use the library in your code.
+## Compile the thrift library
+If you have added Thrift executable into your path, you may just run `client-py/compile.sh` or
+ `client-py/compile.bat`, or you will have to modify it to set variable `THRIFT_EXE` to point to
+your executable. This will generate thrift sources under folder `target`, you can add it to your
+`PYTHONPATH` so that you would be able to use the library in your code. Notice that the scripts
+locate the thrift source file by relative path, so if you move the scripts else where, they are
+no longer valid.
+
+Optionally, if you know the basic usage of thrift, you can only download the thrift source file in
+`service-rpc\src\main\thrift\rpc.thrift`, and simply use `thrift -gen py -out ./target rpc.thrift`
+to generate the python library.
## Example
-We provided an example of how to use the thrift library to connect to IoTDB in `src\client_example.py`, please read it
-carefully before you write your own code.
+We provided an example of how to use the thrift library to connect to IoTDB in `client-py/src
+/client_example.py`, please read it carefully before you write your own code.
\ No newline at end of file
diff --git a/docs/Documentation-CHN/OtherMaterial-Examples.md b/docs/Documentation-CHN/OtherMaterial-Examples.md
index 5ae6f4b..c6d6139 100644
--- a/docs/Documentation-CHN/OtherMaterial-Examples.md
+++ b/docs/Documentation-CHN/OtherMaterial-Examples.md
@@ -81,3 +81,163 @@ public class IotdbHelloWorld {
```
+# 使用Python进行连接
+## 介绍
+以下例子展示了如何使用Thrift编译出Python的库,并调用该库连接IoTDB并进行一些基本操作。在Windows和Linux上的
+使用大同小异,但请注意二者在路径等方面的细微区别。
+
+## Prerequisites
+建议使用python3.7或更高级的版本。
+
+您需要预先安装Thrift才能将我们的Thrift源文件编译为Python的库代码。下面是Thrift的官方安装教程,最终,您需要
+得到一个Thrift的二进制可执行文件。
+```
+http://thrift.apache.org/docs/install/
+```
+
+## Compile the thrift library
+如果您已经将Thrift的可执行文件放到了您的PATH环境变量的目录下,您可以直接运行脚本`client-py/compile.sh`或
+`client-py/compile.bat`,否则您需要修改脚本中的变量`THRIFT_EXE`来指向您的Thrift可执行文件。这会在脚本文件
+的同一目录下生成`target`文件夹,该文件夹即包含了IoTDB的Python版本的Thrift库,当您将该文件夹加入到您的`PYTHONPATH`
+环境变量里后,您就可以在自己的代码中引用该库。请注意,上述脚本通过相对路径寻找我们的Thrift的源文件,如果您改变
+脚本所在位置,脚本可能失效。
+
+或者,如果您对Thrift的基本用法有所了解,您就不需要下载整个项目,您可以仅下载我们的Thrift源文件`service-rpc\src\main\thrift\rpc.thrift`,
+并使用命令`thrift -gen py -out ./target rpc.thrift`来编译Thrift库。
+
+## Example
+下面是一段使用生成的Thrift库连接IoTDB的示例代码,请在编写您自己的代码之前仔细地阅读。
+```python
+import sys, struct
+sys.path.append("../target")
+
+from thrift.protocol import TBinaryProtocol
+from thrift.transport import TSocket, TTransport
+
+from rpc.TSIService import Client, TSCreateTimeseriesReq, TSInsertionReq, TSBatchInsertionReq, TSExecuteStatementReq,\
+ TS_SessionHandle, TSHandleIdentifier, TSOpenSessionReq, TSQueryDataSet, TSFetchResultsReq, TSCloseOperationReq,\
+ TSCloseSessionReq
+
+TSDataType = {
+ 'BOOLEAN' : 0,
+ 'INT32' : 1,
+ 'INT64' : 2,
+ 'FLOAT' : 3,
+ 'DOUBLE' : 4,
+ 'TEXT' : 5
+}
+
+TSEncoding = {
+ 'PLAIN' : 0,
+ 'PLAIN_DICTIONARY' : 1,
+ 'RLE' : 2,
+ 'DIFF' : 3,
+ 'TS_2DIFF' : 4,
+ 'BITMAP' : 5,
+ 'GORILLA' : 6,
+ 'REGULAR' : 7
+}
+
+Compressor = {
+ 'UNCOMPRESSED' : 0,
+ 'SNAPPY' : 1,
+ 'GZIP' : 2,
+ 'LZO' : 3,
+ 'SDT' : 4,
+ 'PAA' : 5,
+ 'PLA' : 6
+}
+
+
+if __name__ == '__main__':
+ ip = "localhost"
+ port = "6667"
+ username = 'root'
+ password = 'root'
+ # Make socket
+ transport = TSocket.TSocket(ip, port)
+
+ # Buffering is critical. Raw sockets are very slow
+ transport = TTransport.TBufferedTransport(transport)
+
+ # Wrap in a protocol
+ protocol = TBinaryProtocol.TBinaryProtocol(transport)
+
+ # Create a client to use the protocol encoder
+ client = Client(protocol)
+
+ # Connect!
+ transport.open()
+
+ # Authentication
+ client.openSession(TSOpenSessionReq(username=username, password=password))
+
+ # This is necessary for resource control
+ stmtId = client.requestStatementId()
+
+ # These two fields do not matter
+ handle = TS_SessionHandle(TSHandleIdentifier(b'uuid', b'secret'))
+
+ # create a storage group
+ status = client.setStorageGroup("root.group1")
+ print(status.statusType)
+
+ # create timeseries
+ status = client.createTimeseries(TSCreateTimeseriesReq("root.group1.s1", TSDataType['INT64'], TSEncoding['PLAIN'],
+ Compressor['UNCOMPRESSED']))
+ print(status.statusType)
+ status = client.createTimeseries(TSCreateTimeseriesReq("root.group1.s2", TSDataType['INT64'], TSEncoding['PLAIN'],
+ Compressor['UNCOMPRESSED']))
+ print(status.statusType)
+ status = client.createTimeseries(TSCreateTimeseriesReq("root.group1.s3", TSDataType['INT64'], TSEncoding['PLAIN'],
+ Compressor['UNCOMPRESSED']))
+ print(status.statusType)
+
+ # insert a single row
+ status = client.insertRow(TSInsertionReq("root.group1", ["s1", "s2", "s3"], ["1", "11", "111"], 1, 1))
+ print(status.statusType)
+
+ # insert multiple rows, this interface is more efficient
+ values = bytearray()
+ times = bytearray()
+ deviceId = "root.group1"
+ measurements = ["s1", "s2", "s3"]
+ dataSize = 3
+ dataTypes = [TSDataType['INT64'], TSDataType['INT64'], TSDataType['INT64']]
+ # the first 3 belong to 's1', the mid 3 belong to 's2', the last 3 belong to 's3'
+ values.extend(struct.pack('>qqqqqqqqq', 2, 3, 4, 22, 33, 44, 222, 333, 444))
+ times.extend(struct.pack('>qqq', 2, 3, 4))
+ resp = client.insertBatch(TSBatchInsertionReq(deviceId, measurements, values, times,
+ dataTypes, dataSize))
+ status = resp.status
+ print(status.statusType)
+
+ # execute deletion (or other statements)
+ resp = client.executeStatement(TSExecuteStatementReq(handle, "DELETE FROM root.group1 where time < 2"))
+ status = resp.status
+ print(status.statusType)
+
+ # query the data
+ stmt = "SELECT * FROM root.group1"
+ fetchSize = 2
+ # this is also for resource control, make sure different queries will not use the same id at the same time
+ queryId = 1
+ resp = client.executeQueryStatement(TSExecuteStatementReq(handle, stmt))
+ stmtHandle = resp.operationHandle
+ status = resp.status
+ print(status.statusType)
+ while True:
+ rst = client.fetchResults(TSFetchResultsReq(stmt, fetchSize, queryId)).queryDataSet
+ records = rst.records
+ if len(records) == 0:
+ break
+ for record in records:
+ print(record)
+
+ # do not forget to close it when a query is over
+ client.closeOperation(TSCloseOperationReq(stmtHandle, queryId, stmtId))
+
+ # and do not forget to close the session before exiting
+ client.closeSession(TSCloseSessionReq(handle))
+
+```
\ No newline at end of file
diff --git a/docs/Documentation/OtherMaterial-Examples.md b/docs/Documentation/OtherMaterial-Examples.md
index c56b650..069b25d 100644
--- a/docs/Documentation/OtherMaterial-Examples.md
+++ b/docs/Documentation/OtherMaterial-Examples.md
@@ -82,3 +82,167 @@ public class IotdbHelloWorld {
```
+
+# Python connection
+## introduction
+This is an example of how to connect to IoTDB with python, using the thrift rpc interfaces. Things
+are almost the same on Windows or Linux, but pay attention to the difference like path separator.
+
+## Prerequisites
+python3.7 or later is preferred.
+
+You have to install Thrift (0.11.0 or later) to compile our thrift file into python code. Below is the official
+tutorial of installation, eventually, you should have a thrift executable.
+```
+http://thrift.apache.org/docs/install/
+```
+
+## Compile the thrift library
+If you have added Thrift executable into your path, you may just run `client-py/compile.sh` or
+ `client-py/compile.bat`, or you will have to modify it to set variable `THRIFT_EXE` to point to
+your executable. This will generate thrift sources under folder `target`, you can add it to your
+`PYTHONPATH` so that you would be able to use the library in your code. Notice that the scripts
+locate the thrift source file by relative path, so if you move the scripts else where, they are
+no longer valid.
+
+Optionally, if you know the basic usage of thrift, you can only download the thrift source file in
+`service-rpc\src\main\thrift\rpc.thrift`, and simply use `thrift -gen py -out ./target rpc.thrift`
+to generate the python library.
+
+## Example
+We provided an example of how to use the thrift library to connect to IoTDB below, please read it
+carefully before you write your own code.
+```python
+import sys, struct
+sys.path.append("../target")
+
+from thrift.protocol import TBinaryProtocol
+from thrift.transport import TSocket, TTransport
+
+from rpc.TSIService import Client, TSCreateTimeseriesReq, TSInsertionReq, TSBatchInsertionReq, TSExecuteStatementReq,\
+ TS_SessionHandle, TSHandleIdentifier, TSOpenSessionReq, TSQueryDataSet, TSFetchResultsReq, TSCloseOperationReq,\
+ TSCloseSessionReq
+
+TSDataType = {
+ 'BOOLEAN' : 0,
+ 'INT32' : 1,
+ 'INT64' : 2,
+ 'FLOAT' : 3,
+ 'DOUBLE' : 4,
+ 'TEXT' : 5
+}
+
+TSEncoding = {
+ 'PLAIN' : 0,
+ 'PLAIN_DICTIONARY' : 1,
+ 'RLE' : 2,
+ 'DIFF' : 3,
+ 'TS_2DIFF' : 4,
+ 'BITMAP' : 5,
+ 'GORILLA' : 6,
+ 'REGULAR' : 7
+}
+
+Compressor = {
+ 'UNCOMPRESSED' : 0,
+ 'SNAPPY' : 1,
+ 'GZIP' : 2,
+ 'LZO' : 3,
+ 'SDT' : 4,
+ 'PAA' : 5,
+ 'PLA' : 6
+}
+
+
+if __name__ == '__main__':
+ ip = "localhost"
+ port = "6667"
+ username = 'root'
+ password = 'root'
+ # Make socket
+ transport = TSocket.TSocket(ip, port)
+
+ # Buffering is critical. Raw sockets are very slow
+ transport = TTransport.TBufferedTransport(transport)
+
+ # Wrap in a protocol
+ protocol = TBinaryProtocol.TBinaryProtocol(transport)
+
+ # Create a client to use the protocol encoder
+ client = Client(protocol)
+
+ # Connect!
+ transport.open()
+
+ # Authentication
+ client.openSession(TSOpenSessionReq(username=username, password=password))
+
+ # This is necessary for resource control
+ stmtId = client.requestStatementId()
+
+ # These two fields do not matter
+ handle = TS_SessionHandle(TSHandleIdentifier(b'uuid', b'secret'))
+
+ # create a storage group
+ status = client.setStorageGroup("root.group1")
+ print(status.statusType)
+
+ # create timeseries
+ status = client.createTimeseries(TSCreateTimeseriesReq("root.group1.s1", TSDataType['INT64'], TSEncoding['PLAIN'],
+ Compressor['UNCOMPRESSED']))
+ print(status.statusType)
+ status = client.createTimeseries(TSCreateTimeseriesReq("root.group1.s2", TSDataType['INT64'], TSEncoding['PLAIN'],
+ Compressor['UNCOMPRESSED']))
+ print(status.statusType)
+ status = client.createTimeseries(TSCreateTimeseriesReq("root.group1.s3", TSDataType['INT64'], TSEncoding['PLAIN'],
+ Compressor['UNCOMPRESSED']))
+ print(status.statusType)
+
+ # insert a single row
+ status = client.insertRow(TSInsertionReq("root.group1", ["s1", "s2", "s3"], ["1", "11", "111"], 1, 1))
+ print(status.statusType)
+
+ # insert multiple rows, this interface is more efficient
+ values = bytearray()
+ times = bytearray()
+ deviceId = "root.group1"
+ measurements = ["s1", "s2", "s3"]
+ dataSize = 3
+ dataTypes = [TSDataType['INT64'], TSDataType['INT64'], TSDataType['INT64']]
+ # the first 3 belong to 's1', the mid 3 belong to 's2', the last 3 belong to 's3'
+ values.extend(struct.pack('>qqqqqqqqq', 2, 3, 4, 22, 33, 44, 222, 333, 444))
+ times.extend(struct.pack('>qqq', 2, 3, 4))
+ resp = client.insertBatch(TSBatchInsertionReq(deviceId, measurements, values, times,
+ dataTypes, dataSize))
+ status = resp.status
+ print(status.statusType)
+
+ # execute deletion (or other statements)
+ resp = client.executeStatement(TSExecuteStatementReq(handle, "DELETE FROM root.group1 where time < 2"))
+ status = resp.status
+ print(status.statusType)
+
+ # query the data
+ stmt = "SELECT * FROM root.group1"
+ fetchSize = 2
+ # this is also for resource control, make sure different queries will not use the same id at the same time
+ queryId = 1
+ resp = client.executeQueryStatement(TSExecuteStatementReq(handle, stmt))
+ stmtHandle = resp.operationHandle
+ status = resp.status
+ print(status.statusType)
+ while True:
+ rst = client.fetchResults(TSFetchResultsReq(stmt, fetchSize, queryId)).queryDataSet
+ records = rst.records
+ if len(records) == 0:
+ break
+ for record in records:
+ print(record)
+
+ # do not forget to close it when a query is over
+ client.closeOperation(TSCloseOperationReq(stmtHandle, queryId, stmtId))
+
+ # and do not forget to close the session before exiting
+ client.closeSession(TSCloseSessionReq(handle))
+
+```
\ No newline at end of file