This is an automated email from the ASF dual-hosted git repository.
haonan pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iotdb.git
The following commit(s) were added to refs/heads/master by this push:
new 93dae13b47 [IOTDB-3351] Add python Client schema template functions:
create template function and drop template function (#6092)
93dae13b47 is described below
commit 93dae13b47f06aac10b1e3ed4a8ce565c84af9d3
Author: Tom <[email protected]>
AuthorDate: Thu Jun 2 09:22:04 2022 +0800
[IOTDB-3351] Add python Client schema template functions: create template
function and drop template function (#6092)
---
client-py/README.md | 31 ++++++++
client-py/SessionExample.py | 49 ++++++++++++
client-py/iotdb/Session.py | 55 ++++++++++++++
client-py/iotdb/template/InternalNode.py | 41 +++++++++++
client-py/iotdb/template/MeasurementNode.py | 56 ++++++++++++++
client-py/iotdb/template/Template.py | 86 ++++++++++++++++++++++
client-py/iotdb/template/TemplateNode.py | 46 ++++++++++++
client-py/iotdb/template/__init__.py | 17 +++++
.../iotdb/tsfile/common/constant/TsFileConstant.py | 36 +++++++++
client-py/iotdb/tsfile/common/constant/__init__.py | 17 +++++
client-py/iotdb/tsfile/utils/Pair.py | 26 +++++++
client-py/iotdb/tsfile/utils/ReadWriteIOUtils.py | 77 +++++++++++++++++++
client-py/iotdb/tsfile/utils/__init__.py | 17 +++++
client-py/tests/test_template.py | 74 +++++++++++++++++++
.../UserGuide/API/Programming-Python-Native-API.md | 31 ++++++++
.../UserGuide/API/Programming-Python-Native-API.md | 31 ++++++++
16 files changed, 690 insertions(+)
diff --git a/client-py/README.md b/client-py/README.md
index 41c0a113b8..e632e400b3 100644
--- a/client-py/README.md
+++ b/client-py/README.md
@@ -274,6 +274,37 @@ session.execute_non_query_statement(sql)
```
+### Schema Template
+#### Create Schema Template
+The step for creating a metadata template is as follows
+1. Create the template class
+2. Adding child Node,InternalNode and MeasurementNode can be chose
+3. Execute create schema template function
+
+```python
+template = Template(name="treeTemplate_python", share_time=True)
+
+i_node_gps = InternalNode(name="GPS", share_time=False)
+i_node_v = InternalNode(name="vehicle", share_time=True)
+m_node_x = MeasurementNode("x", TSDataType.FLOAT, TSEncoding.RLE,
Compressor.SNAPPY)
+
+i_node_gps.add_child(m_node_x)
+i_node_gps.add_child(m_node_x)
+i_node_v.add_child(m_node_x)
+
+template.add_template(i_node_gps)
+template.add_template(i_node_v)
+template.add_template(m_node_x)
+
+session.create_schema_template(template)
+```
+#### Drop Schema Template
+Delete an existing metadata template,dropping an already set template is not
supported
+```python
+session.drop_schema_template("template_python")
+```
+
+
### Pandas Support
To easily transform a query result to a [Pandas
Dataframe](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.html)
diff --git a/client-py/SessionExample.py b/client-py/SessionExample.py
index 93aa839c3b..c34bf553d6 100644
--- a/client-py/SessionExample.py
+++ b/client-py/SessionExample.py
@@ -20,6 +20,9 @@
import numpy as np
from iotdb.Session import Session
+from iotdb.template.InternalNode import InternalNode
+from iotdb.template.MeasurementNode import MeasurementNode
+from iotdb.template.Template import Template
from iotdb.utils.IoTDBConstants import TSDataType, TSEncoding, Compressor
from iotdb.utils.Tablet import Tablet
from iotdb.utils.NumpyTablet import NumpyTablet
@@ -313,6 +316,52 @@ with session.execute_last_data_query(
# delete storage group
session.delete_storage_group("root.sg_test_01")
+# create measurement node template
+template = Template(name="template_python", share_time=False)
+m_node_1 = MeasurementNode(
+ name="s1",
+ data_type=TSDataType.INT64,
+ encoding=TSEncoding.RLE,
+ compression_type=Compressor.SNAPPY,
+)
+m_node_2 = MeasurementNode(
+ name="s2",
+ data_type=TSDataType.INT64,
+ encoding=TSEncoding.RLE,
+ compression_type=Compressor.SNAPPY,
+)
+m_node_3 = MeasurementNode(
+ name="s3",
+ data_type=TSDataType.INT64,
+ encoding=TSEncoding.RLE,
+ compression_type=Compressor.SNAPPY,
+)
+template.add_template(m_node_1)
+template.add_template(m_node_2)
+template.add_template(m_node_3)
+session.create_schema_template(template)
+print("create template success template_python")
+
+# create internal node template
+template = Template(name="treeTemplate_python", share_time=True)
+i_node_gps = InternalNode(name="GPS", share_time=False)
+i_node_v = InternalNode(name="vehicle", share_time=True)
+m_node_x = MeasurementNode("x", TSDataType.FLOAT, TSEncoding.RLE,
Compressor.SNAPPY)
+
+i_node_gps.add_child(m_node_x)
+i_node_gps.add_child(m_node_x)
+i_node_v.add_child(m_node_x)
+template.add_template(i_node_gps)
+template.add_template(i_node_v)
+template.add_template(m_node_x)
+
+session.create_schema_template(template)
+print("create template success treeTemplate_python}")
+
+# drop template
+session.drop_schema_template("template_python")
+session.drop_schema_template("treeTemplate_python")
+print("drop template success, template_python and treeTemplate_python")
# close session connection.
session.close()
diff --git a/client-py/iotdb/Session.py b/client-py/iotdb/Session.py
index 780ecc7d7c..1603c37b2e 100644
--- a/client-py/iotdb/Session.py
+++ b/client-py/iotdb/Session.py
@@ -24,6 +24,7 @@ from iotdb.utils.SessionDataSet import SessionDataSet
from thrift.protocol import TBinaryProtocol, TCompactProtocol
from thrift.transport import TSocket, TTransport
+from .template.Template import Template
from .thrift.rpc.TSIService import (
Client,
TSCreateTimeseriesReq,
@@ -38,6 +39,8 @@ from .thrift.rpc.TSIService import (
TSInsertTabletsReq,
TSInsertRecordsReq,
TSInsertRecordsOfOneDeviceReq,
+ TSCreateSchemaTemplateReq,
+ TSDropSchemaTemplateReq,
)
from .thrift.rpc.ttypes import (
TSDeleteDataReq,
@@ -1033,6 +1036,13 @@ class Session(object):
def execute_raw_data_query(
self, paths: list, start_time: int, end_time: int
) -> SessionDataSet:
+ """
+ execute query statement and returns SessionDataSet
+ :param paths: String path list
+ :param start_time: Query start time
+ :param end_time: Query end time
+ :return: SessionDataSet, contains query results and relevant info (see
SessionDataSet.py)
+ """
request = TSRawDataQueryReq(
self.__session_id,
paths,
@@ -1057,6 +1067,12 @@ class Session(object):
)
def execute_last_data_query(self, paths: list, last_time: int) ->
SessionDataSet:
+ """
+ execute query statement and returns SessionDataSet
+ :param paths: String path list
+ :param last_time: Query last time
+ :return: SessionDataSet, contains query results and relevant info (see
SessionDataSet.py)
+ """
request = TSLastDataQueryReq(
self.__session_id,
paths,
@@ -1088,6 +1104,16 @@ class Session(object):
values_list: list,
have_sorted: bool = False,
):
+ """
+ insert multiple row of string record into database:
+ timestamp, m1, m2, m3
+ 0, text1, text2, text3
+ :param device_id: String, device id
+ :param times: Timestamp list
+ :param measurements_list: Measurements list
+ :param values_list: Value list
+ :param have_sorted: have these list been sorted by timestamp
+ """
if (len(times) != len(measurements_list)) or (len(times) !=
len(values_list)):
raise RuntimeError(
"insert records of one device error: times, measurementsList
and valuesList's size should be equal!"
@@ -1151,3 +1177,32 @@ class Session(object):
is_aligned,
)
return request
+
+ def create_schema_template(self, template: Template):
+ """
+ create schema template, users using this method should use the
template class as an argument
+ :param template: The template contain multiple child node(see
Template.py)
+ """
+ bytes_array = template.serialize()
+ request = TSCreateSchemaTemplateReq(
+ self.__session_id, template.get_name(), bytes_array
+ )
+ status = self.__client.createSchemaTemplate(request)
+ logger.debug(
+ "create one template {} template name:
{}".format(self.__session_id, template.get_name())
+ )
+ return Session.verify_success(status)
+
+ def drop_schema_template(self, template_name: str):
+ """
+ drop schema template, this method should be used to the template unset
anything
+ :param template_name: template name
+ """
+ request = TSDropSchemaTemplateReq(self.__session_id, template_name)
+ status = self.__client.dropSchemaTemplate(request)
+ logger.debug(
+ "drop one template {} template name: {}".format(
+ self.__session_id, template_name
+ )
+ )
+ return Session.verify_success(status)
diff --git a/client-py/iotdb/template/InternalNode.py
b/client-py/iotdb/template/InternalNode.py
new file mode 100644
index 0000000000..bac17ca90a
--- /dev/null
+++ b/client-py/iotdb/template/InternalNode.py
@@ -0,0 +1,41 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+from .TemplateNode import TemplateNode
+
+
+class InternalNode(TemplateNode):
+ def __init__(self, name, share_time):
+ super().__init__(name)
+ self.children = {}
+ self.share_time = share_time
+
+ def add_child(self, node: TemplateNode):
+ if node.get_name() in self.children.keys():
+ assert "Duplicated child of node in template."
+
+ self.children.update({node.get_name(): node})
+
+ def delete_child(self, node):
+ self.children.pop(node.get_name(), None)
+
+ def get_children(self):
+ return self.children
+
+ def is_share_time(self):
+ return self.share_time
diff --git a/client-py/iotdb/template/MeasurementNode.py
b/client-py/iotdb/template/MeasurementNode.py
new file mode 100644
index 0000000000..7d96d4bc0d
--- /dev/null
+++ b/client-py/iotdb/template/MeasurementNode.py
@@ -0,0 +1,56 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+from iotdb.utils.IoTDBConstants import TSDataType, TSEncoding, Compressor
+from .TemplateNode import TemplateNode
+from ..tsfile.utils.ReadWriteIOUtils import ReadWriteUtils
+
+
+class MeasurementNode(TemplateNode):
+ def __init__(
+ self,
+ name: str,
+ data_type: TSDataType,
+ encoding: TSEncoding,
+ compression_type: Compressor,
+ ):
+ self.name = name
+ self.data_type = data_type
+ self.encoding = encoding
+ self.compression_type = compression_type
+
+ def is_measurement(self):
+ return True
+
+ def get_data_type(self):
+ return self.data_type
+
+ def get_encoding(self):
+ return self.encoding
+
+ def get_compression_type(self):
+ return self.compression_type
+
+ def serialize(self, *args, **kwargs):
+ format_str_list, values_tobe_packed = args
+ ReadWriteUtils.write(self.get_name(), format_str_list,
values_tobe_packed)
+ ReadWriteUtils.write(self.get_data_type(), format_str_list,
values_tobe_packed)
+ ReadWriteUtils.write(self.get_encoding(), format_str_list,
values_tobe_packed)
+ ReadWriteUtils.write(
+ self.get_compression_type(), format_str_list, values_tobe_packed
+ )
diff --git a/client-py/iotdb/template/Template.py
b/client-py/iotdb/template/Template.py
new file mode 100644
index 0000000000..d5137d3343
--- /dev/null
+++ b/client-py/iotdb/template/Template.py
@@ -0,0 +1,86 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+import struct
+
+from .TemplateNode import TemplateNode
+from ..tsfile.common.constant.TsFileConstant import TsFileConstant
+from ..tsfile.utils.Pair import Pair
+from ..tsfile.utils.ReadWriteIOUtils import ReadWriteUtils
+
+
+class Template:
+ def __init__(self, name, share_time: bool = False):
+ self.name = name
+ self.children = dict()
+ self.share_time = share_time
+
+ def get_name(self) -> object:
+ return self.name
+
+ def is_share_time(self) -> object:
+ return self.share_time
+
+ def set_share_time(self, share_time: bool):
+ self.share_time = share_time
+
+ def add_template(self, child: TemplateNode):
+ if self.children.get(child.get_name()):
+ raise Exception("Duplicated child of node in template.")
+ self.children.update({child.get_name(): child})
+
+ def delete_from_template(self, name: str):
+ if not self.children.pop(name, []):
+ raise Exception("It is not a direct child of the template: " +
name)
+
+ def serialize(self):
+ format_str_list = [">"]
+ values_tobe_packed = []
+ stack = []
+ aligned_prefix = set()
+ ReadWriteUtils.write(self.get_name(), format_str_list,
values_tobe_packed)
+ ReadWriteUtils.write(self.is_share_time(), format_str_list,
values_tobe_packed)
+ if self.is_share_time():
+ aligned_prefix.add("")
+
+ for child in self.children:
+ stack.append(Pair("", self.children[child]))
+
+ while stack:
+ pair = stack.pop()
+ prefix = pair.left
+ cur_node = pair.right
+ full_path = list()
+ if not cur_node.is_measurement():
+ if prefix != "":
+ full_path.append(TsFileConstant.PATH_SEPARATOR)
+ full_path.append(cur_node.get_name())
+ if cur_node.is_share_time():
+ aligned_prefix.add("".join(full_path))
+ for child in cur_node.children:
+ stack.append(Pair("".join(full_path),
self.children[child]))
+ else:
+ ReadWriteUtils.write(prefix, format_str_list,
values_tobe_packed)
+ if prefix in aligned_prefix:
+ ReadWriteUtils.write(True, format_str_list,
values_tobe_packed)
+ else:
+ ReadWriteUtils.write(False, format_str_list,
values_tobe_packed)
+ cur_node.serialize(format_str_list, values_tobe_packed)
+
+ format_str = "".join(format_str_list)
+ return struct.pack(format_str, *values_tobe_packed)
diff --git a/client-py/iotdb/template/TemplateNode.py
b/client-py/iotdb/template/TemplateNode.py
new file mode 100644
index 0000000000..62a6c70eac
--- /dev/null
+++ b/client-py/iotdb/template/TemplateNode.py
@@ -0,0 +1,46 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+
+class TemplateNode(object):
+ """
+ Template class, this class should be used to schema template node
+ """
+ def __init__(self, name):
+ self.name = name
+
+ def get_name(self):
+ return self.name
+
+ def get_children(self):
+ return None
+
+ def add_child(self, node):
+ ...
+
+ def delete_child(self, node):
+ ...
+
+ def is_measurement(self):
+ return False
+
+ def is_share_time(self):
+ return False
+
+ def serialize(self, buffer):
+ ...
diff --git a/client-py/iotdb/template/__init__.py
b/client-py/iotdb/template/__init__.py
new file mode 100644
index 0000000000..2a1e720805
--- /dev/null
+++ b/client-py/iotdb/template/__init__.py
@@ -0,0 +1,17 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
diff --git a/client-py/iotdb/tsfile/common/constant/TsFileConstant.py
b/client-py/iotdb/tsfile/common/constant/TsFileConstant.py
new file mode 100644
index 0000000000..0baad6a5fb
--- /dev/null
+++ b/client-py/iotdb/tsfile/common/constant/TsFileConstant.py
@@ -0,0 +1,36 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+
+class TsFileConstant:
+ TSFILE_SUFFIX = ".tsfile"
+ TSFILE_HOME = "TSFILE_HOME"
+ TSFILE_CONF = "TSFILE_CONF"
+ PATH_ROOT = "root"
+ TMP_SUFFIX = "tmp"
+ PATH_SEPARATOR = "."
+ PATH_SEPARATOR_CHAR = "."
+ PATH_SEPARATER_NO_REGEX = "\\."
+ DOUBLE_QUOTE = '"'
+
+ TIME_COLUMN_MASK = 0x80
+
+ VALUE_COLUMN_MASK = 0x40
+
+ def __ts_file_constant(self):
+ ...
diff --git a/client-py/iotdb/tsfile/common/constant/__init__.py
b/client-py/iotdb/tsfile/common/constant/__init__.py
new file mode 100644
index 0000000000..2a1e720805
--- /dev/null
+++ b/client-py/iotdb/tsfile/common/constant/__init__.py
@@ -0,0 +1,17 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
diff --git a/client-py/iotdb/tsfile/utils/Pair.py
b/client-py/iotdb/tsfile/utils/Pair.py
new file mode 100644
index 0000000000..70bb3f7258
--- /dev/null
+++ b/client-py/iotdb/tsfile/utils/Pair.py
@@ -0,0 +1,26 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+from iotdb.template.TemplateNode import TemplateNode
+
+
+class Pair:
+ def __init__(self, left: str, right: TemplateNode):
+ self.__serialVersionUID = -1398609631703707002
+ self.left = left
+ self.right = right
diff --git a/client-py/iotdb/tsfile/utils/ReadWriteIOUtils.py
b/client-py/iotdb/tsfile/utils/ReadWriteIOUtils.py
new file mode 100644
index 0000000000..6101906ced
--- /dev/null
+++ b/client-py/iotdb/tsfile/utils/ReadWriteIOUtils.py
@@ -0,0 +1,77 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+from iotdb.utils.IoTDBConstants import TSDataType, TSEncoding, Compressor
+
+
+class ReadWriteUtils:
+ BOOLEAN_LEN = 1
+ SHORT_LEN = 2
+ INT_LEN = 4
+ LONG_LEN = 8
+ DOUBLE_LEN = 8
+ FLOAT_LEN = 4
+ BIT_LEN = 0.125
+ NO_BYTE_TO_READ = -1
+ magicStringBytes = []
+ RETURN_ERROR = "Intend to read %d bytes but %d are actually returned"
+ URN_ERROR = "Intend to read %d bytes but %d are actually returned"
+
+ @classmethod
+ def write(cls, *args, **kwargs):
+ value, format_str_list, values_tobe_packed = args
+ if isinstance(value, bool):
+ cls.write_bool(value, format_str_list, values_tobe_packed)
+ elif isinstance(value, str):
+ cls.write_str(value, format_str_list, values_tobe_packed)
+ elif isinstance(value, int):
+ cls.write_int(value, format_str_list, values_tobe_packed)
+ elif isinstance(value, TSDataType):
+ cls.write_byte(value.value, format_str_list, values_tobe_packed)
+ elif isinstance(value, TSEncoding):
+ cls.write_byte(value.value, format_str_list, values_tobe_packed)
+ elif isinstance(value, Compressor):
+ cls.write_byte(value.value, format_str_list, values_tobe_packed)
+
+ @classmethod
+ def write_str(cls, s: str, format_str_list, values_tobe_packed):
+ if s is None:
+ cls.write_int(cls.NO_BYTE_TO_READ, format_str_list,
values_tobe_packed)
+
+ value_bytes = bytes(s, "utf-8")
+ format_str_list.append("i")
+ format_str_list.append(str(len(value_bytes)))
+ format_str_list.append("s")
+
+ values_tobe_packed.append(len(value_bytes))
+ values_tobe_packed.append(value_bytes)
+
+ @classmethod
+ def write_int(cls, i: int, format_str_list, values_tobe_packed):
+ format_str_list.append("i")
+ values_tobe_packed.append(i)
+
+ @classmethod
+ def write_bool(cls, flag: bool, format_str_list, values_tobe_packed):
+ format_str_list.append("?")
+ values_tobe_packed.append(flag)
+
+ @classmethod
+ def write_byte(cls, b, format_str_list, values_tobe_packed):
+ format_str_list.append("b")
+ values_tobe_packed.append(b)
diff --git a/client-py/iotdb/tsfile/utils/__init__.py
b/client-py/iotdb/tsfile/utils/__init__.py
new file mode 100644
index 0000000000..2a1e720805
--- /dev/null
+++ b/client-py/iotdb/tsfile/utils/__init__.py
@@ -0,0 +1,17 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
diff --git a/client-py/tests/test_template.py b/client-py/tests/test_template.py
new file mode 100644
index 0000000000..0b8a84aefd
--- /dev/null
+++ b/client-py/tests/test_template.py
@@ -0,0 +1,74 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+from iotdb.IoTDBContainer import IoTDBContainer
+from iotdb.Session import Session
+from iotdb.template.InternalNode import InternalNode
+from iotdb.template.MeasurementNode import MeasurementNode
+from iotdb.template.Template import Template
+from iotdb.utils.IoTDBConstants import TSDataType, Compressor, TSEncoding
+
+
+def test_template_create():
+ with IoTDBContainer("iotdb:dev") as db:
+ db: IoTDBContainer
+ session = Session(db.get_container_host_ip(),
db.get_exposed_port(6667))
+ session.open(False)
+
+ template = Template(name="template_python", share_time=False)
+ m_node_1 = MeasurementNode(
+ name="s1",
+ data_type=TSDataType.INT64,
+ encoding=TSEncoding.RLE,
+ compression_type=Compressor.SNAPPY,
+ )
+ m_node_2 = MeasurementNode(
+ name="s2",
+ data_type=TSDataType.INT64,
+ encoding=TSEncoding.RLE,
+ compression_type=Compressor.SNAPPY,
+ )
+ m_node_3 = MeasurementNode(
+ name="s3",
+ data_type=TSDataType.INT64,
+ encoding=TSEncoding.RLE,
+ compression_type=Compressor.SNAPPY,
+ )
+ template.add_template(m_node_1)
+ template.add_template(m_node_2)
+ template.add_template(m_node_3)
+ session.create_schema_template(template)
+
+ template = Template(name="treeTemplate_python", share_time=True)
+ i_node_gps = InternalNode(name="GPS", share_time=False)
+ i_node_v = InternalNode(name="vehicle", share_time=True)
+ m_node_x = MeasurementNode(
+ "x", TSDataType.FLOAT, TSEncoding.RLE, Compressor.SNAPPY
+ )
+
+ i_node_gps.add_child(m_node_x)
+ i_node_gps.add_child(m_node_x)
+ i_node_v.add_child(m_node_x)
+ template.add_template(i_node_gps)
+ template.add_template(i_node_v)
+ template.add_template(m_node_x)
+ session.create_schema_template(template)
+
+ session.drop_schema_template("template_python")
+ session.drop_schema_template("treeTemplate_python")
+
+ session.close()
diff --git a/docs/UserGuide/API/Programming-Python-Native-API.md
b/docs/UserGuide/API/Programming-Python-Native-API.md
index c200586bbf..30799133e2 100644
--- a/docs/UserGuide/API/Programming-Python-Native-API.md
+++ b/docs/UserGuide/API/Programming-Python-Native-API.md
@@ -252,6 +252,37 @@ session.execute_non_query_statement(sql)
```
+### Schema Template
+#### Create Schema Template
+The step for creating a metadata template is as follows
+1. Create the template class
+2. Adding child Node,InternalNode and MeasurementNode can be chose
+3. Execute create schema template function
+
+```python
+template = Template(name="treeTemplate_python", share_time=True)
+
+i_node_gps = InternalNode(name="GPS", share_time=False)
+i_node_v = InternalNode(name="vehicle", share_time=True)
+m_node_x = MeasurementNode("x", TSDataType.FLOAT, TSEncoding.RLE,
Compressor.SNAPPY)
+
+i_node_gps.add_child(m_node_x)
+i_node_gps.add_child(m_node_x)
+i_node_v.add_child(m_node_x)
+
+template.add_template(i_node_gps)
+template.add_template(i_node_v)
+template.add_template(m_node_x)
+
+session.create_schema_template(template)
+```
+#### Drop Schema Template
+Delete an existing metadata template,dropping an already set template is not
supported
+```python
+session.drop_schema_template("template_python")
+```
+
+
### Pandas Support
To easily transform a query result to a [Pandas
Dataframe](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.html)
diff --git a/docs/zh/UserGuide/API/Programming-Python-Native-API.md
b/docs/zh/UserGuide/API/Programming-Python-Native-API.md
index 55fc59d031..aec3c832a1 100644
--- a/docs/zh/UserGuide/API/Programming-Python-Native-API.md
+++ b/docs/zh/UserGuide/API/Programming-Python-Native-API.md
@@ -246,6 +246,37 @@ session.execute_query_statement(sql)
session.execute_non_query_statement(sql)
```
+
+### 元数据模版接口
+#### 构建元数据模版
+1. 首先构建Template类
+2. 添加子节点,可以选择InternalNode或MeasurementNode
+3. 调用创建元数据模版接口
+
+```python
+template = Template(name="treeTemplate_python", share_time=True)
+
+i_node_gps = InternalNode(name="GPS", share_time=False)
+i_node_v = InternalNode(name="vehicle", share_time=True)
+m_node_x = MeasurementNode("x", TSDataType.FLOAT, TSEncoding.RLE,
Compressor.SNAPPY)
+
+i_node_gps.add_child(m_node_x)
+i_node_gps.add_child(m_node_x)
+i_node_v.add_child(m_node_x)
+
+template.add_template(i_node_gps)
+template.add_template(i_node_v)
+template.add_template(m_node_x)
+
+session.create_schema_template(template)
+```
+#### 删除元数据模版
+删除已经存在的元数据模版,不支持删除已经挂载的模版
+```python
+session.drop_schema_template("template_python")
+```
+
+
### 对 Pandas 的支持
我们支持将查询结果轻松地转换为 [Pandas
Dataframe](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.html)。