apache-iotdb 1.3.3__tar.gz → 2.0.1b0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. {apache_iotdb-1.3.3 → apache_iotdb-2.0.1b0}/PKG-INFO +5 -5
  2. {apache_iotdb-1.3.3 → apache_iotdb-2.0.1b0}/README.md +2 -2
  3. {apache_iotdb-1.3.3 → apache_iotdb-2.0.1b0}/apache_iotdb.egg-info/PKG-INFO +5 -5
  4. {apache_iotdb-1.3.3 → apache_iotdb-2.0.1b0}/apache_iotdb.egg-info/SOURCES.txt +11 -6
  5. {apache_iotdb-1.3.3 → apache_iotdb-2.0.1b0}/apache_iotdb.egg-info/requires.txt +1 -1
  6. {apache_iotdb-1.3.3 → apache_iotdb-2.0.1b0}/iotdb/Session.py +221 -22
  7. {apache_iotdb-1.3.3 → apache_iotdb-2.0.1b0}/iotdb/SessionPool.py +11 -0
  8. {apache_iotdb-1.3.3 → apache_iotdb-2.0.1b0}/iotdb/sqlalchemy/IoTDBDialect.py +11 -4
  9. apache_iotdb-2.0.1b0/iotdb/table_session.py +147 -0
  10. apache_iotdb-2.0.1b0/iotdb/table_session_pool.py +116 -0
  11. {apache_iotdb-1.3.3 → apache_iotdb-2.0.1b0}/iotdb/thrift/common/ttypes.py +54 -0
  12. {apache_iotdb-1.3.3 → apache_iotdb-2.0.1b0}/iotdb/thrift/rpc/IClientRPCService.py +12 -12
  13. {apache_iotdb-1.3.3 → apache_iotdb-2.0.1b0}/iotdb/thrift/rpc/ttypes.py +601 -493
  14. {apache_iotdb-1.3.3 → apache_iotdb-2.0.1b0}/iotdb/utils/Field.py +0 -1
  15. {apache_iotdb-1.3.3 → apache_iotdb-2.0.1b0}/iotdb/utils/IoTDBRpcDataSet.py +4 -1
  16. {apache_iotdb-1.3.3 → apache_iotdb-2.0.1b0}/iotdb/utils/NumpyTablet.py +39 -14
  17. {apache_iotdb-1.3.3 → apache_iotdb-2.0.1b0}/iotdb/utils/Tablet.py +50 -14
  18. {apache_iotdb-1.3.3 → apache_iotdb-2.0.1b0}/pyproject.toml +3 -3
  19. {apache_iotdb-1.3.3/iotdb/dbapi/tests → apache_iotdb-2.0.1b0/tests/integration/dbapi}/test_connection.py +1 -1
  20. {apache_iotdb-1.3.3/iotdb/dbapi/tests → apache_iotdb-2.0.1b0/tests/integration/dbapi}/test_cursor.py +1 -1
  21. {apache_iotdb-1.3.3/iotdb/sqlalchemy/tests → apache_iotdb-2.0.1b0/tests/integration/sqlalchemy}/test_dialect.py +28 -15
  22. {apache_iotdb-1.3.3 → apache_iotdb-2.0.1b0}/tests/integration/test_aligned_timeseries.py +1 -1
  23. {apache_iotdb-1.3.3 → apache_iotdb-2.0.1b0}/tests/integration/test_dataframe.py +1 -1
  24. {apache_iotdb-1.3.3 → apache_iotdb-2.0.1b0}/tests/integration/test_delete_data.py +1 -1
  25. {apache_iotdb-1.3.3 → apache_iotdb-2.0.1b0}/tests/integration/test_new_data_types.py +1 -1
  26. {apache_iotdb-1.3.3 → apache_iotdb-2.0.1b0}/tests/integration/test_one_device.py +1 -1
  27. apache_iotdb-2.0.1b0/tests/integration/test_relational_session.py +128 -0
  28. {apache_iotdb-1.3.3 → apache_iotdb-2.0.1b0}/tests/integration/test_session.py +82 -20
  29. {apache_iotdb-1.3.3 → apache_iotdb-2.0.1b0}/tests/integration/test_session_pool.py +1 -1
  30. apache_iotdb-2.0.1b0/tests/integration/test_tablemodel_insert.py +1592 -0
  31. {apache_iotdb-1.3.3 → apache_iotdb-2.0.1b0}/tests/integration/test_tablet.py +1 -1
  32. {apache_iotdb-1.3.3 → apache_iotdb-2.0.1b0}/tests/integration/test_todf.py +1 -1
  33. apache_iotdb-2.0.1b0/tests/integration/test_treemodel_insert.py +6027 -0
  34. {apache_iotdb-1.3.3 → apache_iotdb-2.0.1b0}/apache_iotdb.egg-info/dependency_links.txt +0 -0
  35. {apache_iotdb-1.3.3 → apache_iotdb-2.0.1b0}/apache_iotdb.egg-info/entry_points.txt +0 -0
  36. {apache_iotdb-1.3.3 → apache_iotdb-2.0.1b0}/apache_iotdb.egg-info/top_level.txt +0 -0
  37. {apache_iotdb-1.3.3 → apache_iotdb-2.0.1b0}/iotdb/__init__.py +0 -0
  38. {apache_iotdb-1.3.3 → apache_iotdb-2.0.1b0}/iotdb/dbapi/Connection.py +0 -0
  39. {apache_iotdb-1.3.3 → apache_iotdb-2.0.1b0}/iotdb/dbapi/Cursor.py +0 -0
  40. {apache_iotdb-1.3.3 → apache_iotdb-2.0.1b0}/iotdb/dbapi/Exceptions.py +0 -0
  41. {apache_iotdb-1.3.3 → apache_iotdb-2.0.1b0}/iotdb/dbapi/__init__.py +0 -0
  42. {apache_iotdb-1.3.3 → apache_iotdb-2.0.1b0}/iotdb/sqlalchemy/IoTDBIdentifierPreparer.py +0 -0
  43. {apache_iotdb-1.3.3 → apache_iotdb-2.0.1b0}/iotdb/sqlalchemy/IoTDBSQLCompiler.py +0 -0
  44. {apache_iotdb-1.3.3 → apache_iotdb-2.0.1b0}/iotdb/sqlalchemy/IoTDBTypeCompiler.py +0 -0
  45. {apache_iotdb-1.3.3/iotdb/dbapi/tests → apache_iotdb-2.0.1b0/iotdb/sqlalchemy}/__init__.py +0 -0
  46. {apache_iotdb-1.3.3 → apache_iotdb-2.0.1b0}/iotdb/template/MeasurementNode.py +0 -0
  47. {apache_iotdb-1.3.3 → apache_iotdb-2.0.1b0}/iotdb/template/Template.py +0 -0
  48. {apache_iotdb-1.3.3 → apache_iotdb-2.0.1b0}/iotdb/template/TemplateNode.py +0 -0
  49. {apache_iotdb-1.3.3 → apache_iotdb-2.0.1b0}/iotdb/template/TemplateQueryType.py +0 -0
  50. {apache_iotdb-1.3.3/iotdb/sqlalchemy → apache_iotdb-2.0.1b0/iotdb/template}/__init__.py +0 -0
  51. {apache_iotdb-1.3.3 → apache_iotdb-2.0.1b0}/iotdb/thrift/__init__.py +0 -0
  52. {apache_iotdb-1.3.3 → apache_iotdb-2.0.1b0}/iotdb/thrift/common/__init__.py +0 -0
  53. {apache_iotdb-1.3.3 → apache_iotdb-2.0.1b0}/iotdb/thrift/common/constants.py +0 -0
  54. {apache_iotdb-1.3.3 → apache_iotdb-2.0.1b0}/iotdb/thrift/rpc/__init__.py +0 -0
  55. {apache_iotdb-1.3.3 → apache_iotdb-2.0.1b0}/iotdb/thrift/rpc/constants.py +0 -0
  56. {apache_iotdb-1.3.3/iotdb/sqlalchemy/tests → apache_iotdb-2.0.1b0/iotdb/tsfile}/__init__.py +0 -0
  57. {apache_iotdb-1.3.3/iotdb/template → apache_iotdb-2.0.1b0/iotdb/tsfile/common}/__init__.py +0 -0
  58. {apache_iotdb-1.3.3 → apache_iotdb-2.0.1b0}/iotdb/tsfile/common/constant/TsFileConstant.py +0 -0
  59. {apache_iotdb-1.3.3/iotdb/tsfile → apache_iotdb-2.0.1b0/iotdb/tsfile/common/constant}/__init__.py +0 -0
  60. {apache_iotdb-1.3.3 → apache_iotdb-2.0.1b0}/iotdb/tsfile/utils/DateUtils.py +0 -0
  61. {apache_iotdb-1.3.3 → apache_iotdb-2.0.1b0}/iotdb/tsfile/utils/Pair.py +0 -0
  62. {apache_iotdb-1.3.3 → apache_iotdb-2.0.1b0}/iotdb/tsfile/utils/ReadWriteIOUtils.py +0 -0
  63. {apache_iotdb-1.3.3/iotdb/tsfile/common → apache_iotdb-2.0.1b0/iotdb/tsfile/utils}/__init__.py +0 -0
  64. {apache_iotdb-1.3.3 → apache_iotdb-2.0.1b0}/iotdb/utils/BitMap.py +0 -0
  65. {apache_iotdb-1.3.3 → apache_iotdb-2.0.1b0}/iotdb/utils/IoTDBConnectionException.py +0 -0
  66. {apache_iotdb-1.3.3 → apache_iotdb-2.0.1b0}/iotdb/utils/IoTDBConstants.py +0 -0
  67. {apache_iotdb-1.3.3 → apache_iotdb-2.0.1b0}/iotdb/utils/RowRecord.py +0 -0
  68. {apache_iotdb-1.3.3 → apache_iotdb-2.0.1b0}/iotdb/utils/SessionDataSet.py +0 -0
  69. {apache_iotdb-1.3.3/iotdb/tsfile/common/constant → apache_iotdb-2.0.1b0/iotdb/utils}/__init__.py +0 -0
  70. {apache_iotdb-1.3.3 → apache_iotdb-2.0.1b0}/setup.cfg +0 -0
  71. {apache_iotdb-1.3.3/iotdb/tsfile/utils → apache_iotdb-2.0.1b0/tests}/__init__.py +0 -0
  72. {apache_iotdb-1.3.3/iotdb/utils → apache_iotdb-2.0.1b0/tests/integration}/__init__.py +0 -0
  73. {apache_iotdb-1.3.3/tests → apache_iotdb-2.0.1b0/tests/integration/dbapi}/__init__.py +0 -0
  74. /apache_iotdb-1.3.3/iotdb/IoTDBContainer.py → /apache_iotdb-2.0.1b0/tests/integration/iotdb_container.py +0 -0
  75. {apache_iotdb-1.3.3/tests/integration → apache_iotdb-2.0.1b0/tests/integration/sqlalchemy}/__init__.py +0 -0
  76. {apache_iotdb-1.3.3 → apache_iotdb-2.0.1b0}/tests/integration/tablet_performance_comparison.py +0 -0
  77. {apache_iotdb-1.3.3 → apache_iotdb-2.0.1b0}/tests/unit/__init__.py +0 -0
  78. {apache_iotdb-1.3.3 → apache_iotdb-2.0.1b0}/tests/unit/test_numpy_tablet.py +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: apache-iotdb
3
- Version: 1.3.3
3
+ Version: 2.0.1b0
4
4
  Summary: Apache IoTDB client API
5
5
  Author-email: Apache IoTDB <dev@iotdb.apache.org>
6
6
  License: Apache License, Version 2.0
@@ -17,7 +17,7 @@ Description-Content-Type: text/markdown
17
17
  Requires-Dist: thrift>=0.14.1
18
18
  Requires-Dist: pandas>=1.0.0
19
19
  Requires-Dist: numpy>=1.0.0
20
- Requires-Dist: sqlalchemy<1.5,>=1.4
20
+ Requires-Dist: sqlalchemy>=1.4
21
21
  Requires-Dist: sqlalchemy-utils>=0.37.8
22
22
 
23
23
  <!--
@@ -69,9 +69,9 @@ You have to install thrift (>=0.14.1) before using the package.
69
69
 
70
70
  First, download the latest package: `pip3 install apache-iotdb`
71
71
 
72
- You can get an example of using the package to read and write data at here: [Example](https://github.com/apache/iotdb/blob/master/client-py/SessionExample.py)
72
+ You can get an example of using the package to read and write data at here: [Example](https://github.com/apache/iotdb/blob/master/iotdb-client/client-py/SessionExample.py)
73
73
 
74
- An example of aligned timeseries: [Aligned Timeseries Session Example](https://github.com/apache/iotdb/blob/master/client-py/SessionAlignedTimeseriesExample.py)
74
+ An example of aligned timeseries: [Aligned Timeseries Session Example](https://github.com/apache/iotdb/blob/master/iotdb-client/client-py/SessionAlignedTimeseriesExample.py)
75
75
 
76
76
  (you need to add `import iotdb` in the head of the file)
77
77
 
@@ -47,9 +47,9 @@ You have to install thrift (>=0.14.1) before using the package.
47
47
 
48
48
  First, download the latest package: `pip3 install apache-iotdb`
49
49
 
50
- You can get an example of using the package to read and write data at here: [Example](https://github.com/apache/iotdb/blob/master/client-py/SessionExample.py)
50
+ You can get an example of using the package to read and write data at here: [Example](https://github.com/apache/iotdb/blob/master/iotdb-client/client-py/SessionExample.py)
51
51
 
52
- An example of aligned timeseries: [Aligned Timeseries Session Example](https://github.com/apache/iotdb/blob/master/client-py/SessionAlignedTimeseriesExample.py)
52
+ An example of aligned timeseries: [Aligned Timeseries Session Example](https://github.com/apache/iotdb/blob/master/iotdb-client/client-py/SessionAlignedTimeseriesExample.py)
53
53
 
54
54
  (you need to add `import iotdb` in the head of the file)
55
55
 
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: apache-iotdb
3
- Version: 1.3.3
3
+ Version: 2.0.1b0
4
4
  Summary: Apache IoTDB client API
5
5
  Author-email: Apache IoTDB <dev@iotdb.apache.org>
6
6
  License: Apache License, Version 2.0
@@ -17,7 +17,7 @@ Description-Content-Type: text/markdown
17
17
  Requires-Dist: thrift>=0.14.1
18
18
  Requires-Dist: pandas>=1.0.0
19
19
  Requires-Dist: numpy>=1.0.0
20
- Requires-Dist: sqlalchemy<1.5,>=1.4
20
+ Requires-Dist: sqlalchemy>=1.4
21
21
  Requires-Dist: sqlalchemy-utils>=0.37.8
22
22
 
23
23
  <!--
@@ -69,9 +69,9 @@ You have to install thrift (>=0.14.1) before using the package.
69
69
 
70
70
  First, download the latest package: `pip3 install apache-iotdb`
71
71
 
72
- You can get an example of using the package to read and write data at here: [Example](https://github.com/apache/iotdb/blob/master/client-py/SessionExample.py)
72
+ You can get an example of using the package to read and write data at here: [Example](https://github.com/apache/iotdb/blob/master/iotdb-client/client-py/SessionExample.py)
73
73
 
74
- An example of aligned timeseries: [Aligned Timeseries Session Example](https://github.com/apache/iotdb/blob/master/client-py/SessionAlignedTimeseriesExample.py)
74
+ An example of aligned timeseries: [Aligned Timeseries Session Example](https://github.com/apache/iotdb/blob/master/iotdb-client/client-py/SessionAlignedTimeseriesExample.py)
75
75
 
76
76
  (you need to add `import iotdb` in the head of the file)
77
77
 
@@ -6,24 +6,20 @@ apache_iotdb.egg-info/dependency_links.txt
6
6
  apache_iotdb.egg-info/entry_points.txt
7
7
  apache_iotdb.egg-info/requires.txt
8
8
  apache_iotdb.egg-info/top_level.txt
9
- iotdb/IoTDBContainer.py
10
9
  iotdb/Session.py
11
10
  iotdb/SessionPool.py
12
11
  iotdb/__init__.py
12
+ iotdb/table_session.py
13
+ iotdb/table_session_pool.py
13
14
  iotdb/dbapi/Connection.py
14
15
  iotdb/dbapi/Cursor.py
15
16
  iotdb/dbapi/Exceptions.py
16
17
  iotdb/dbapi/__init__.py
17
- iotdb/dbapi/tests/__init__.py
18
- iotdb/dbapi/tests/test_connection.py
19
- iotdb/dbapi/tests/test_cursor.py
20
18
  iotdb/sqlalchemy/IoTDBDialect.py
21
19
  iotdb/sqlalchemy/IoTDBIdentifierPreparer.py
22
20
  iotdb/sqlalchemy/IoTDBSQLCompiler.py
23
21
  iotdb/sqlalchemy/IoTDBTypeCompiler.py
24
22
  iotdb/sqlalchemy/__init__.py
25
- iotdb/sqlalchemy/tests/__init__.py
26
- iotdb/sqlalchemy/tests/test_dialect.py
27
23
  iotdb/template/MeasurementNode.py
28
24
  iotdb/template/Template.py
29
25
  iotdb/template/TemplateNode.py
@@ -57,15 +53,24 @@ iotdb/utils/Tablet.py
57
53
  iotdb/utils/__init__.py
58
54
  tests/__init__.py
59
55
  tests/integration/__init__.py
56
+ tests/integration/iotdb_container.py
60
57
  tests/integration/tablet_performance_comparison.py
61
58
  tests/integration/test_aligned_timeseries.py
62
59
  tests/integration/test_dataframe.py
63
60
  tests/integration/test_delete_data.py
64
61
  tests/integration/test_new_data_types.py
65
62
  tests/integration/test_one_device.py
63
+ tests/integration/test_relational_session.py
66
64
  tests/integration/test_session.py
67
65
  tests/integration/test_session_pool.py
66
+ tests/integration/test_tablemodel_insert.py
68
67
  tests/integration/test_tablet.py
69
68
  tests/integration/test_todf.py
69
+ tests/integration/test_treemodel_insert.py
70
+ tests/integration/dbapi/__init__.py
71
+ tests/integration/dbapi/test_connection.py
72
+ tests/integration/dbapi/test_cursor.py
73
+ tests/integration/sqlalchemy/__init__.py
74
+ tests/integration/sqlalchemy/test_dialect.py
70
75
  tests/unit/__init__.py
71
76
  tests/unit/test_numpy_tablet.py
@@ -1,5 +1,5 @@
1
1
  thrift>=0.14.1
2
2
  pandas>=1.0.0
3
3
  numpy>=1.0.0
4
- sqlalchemy<1.5,>=1.4
4
+ sqlalchemy>=1.4
5
5
  sqlalchemy-utils>=0.37.8
@@ -69,11 +69,12 @@ class Session(object):
69
69
  SUCCESS_STATUS = 200
70
70
  MULTIPLE_ERROR = 302
71
71
  REDIRECTION_RECOMMEND = 400
72
- DEFAULT_FETCH_SIZE = 10000
72
+ DEFAULT_FETCH_SIZE = 5000
73
73
  DEFAULT_USER = "root"
74
74
  DEFAULT_PASSWORD = "root"
75
75
  DEFAULT_ZONE_ID = time.strftime("%z")
76
76
  RETRY_NUM = 3
77
+ SQL_DIALECT = "tree"
77
78
 
78
79
  def __init__(
79
80
  self,
@@ -104,6 +105,8 @@ class Session(object):
104
105
  self.__enable_redirection = enable_redirection
105
106
  self.__device_id_to_endpoint = None
106
107
  self.__endpoint_to_connection = None
108
+ self.sql_dialect = self.SQL_DIALECT
109
+ self.database = None
107
110
 
108
111
  @classmethod
109
112
  def init_from_node_urls(
@@ -118,7 +121,13 @@ class Session(object):
118
121
  if node_urls is None:
119
122
  raise RuntimeError("node urls is empty")
120
123
  session = Session(
121
- None, None, user, password, fetch_size, zone_id, enable_redirection
124
+ None,
125
+ None,
126
+ user,
127
+ password,
128
+ fetch_size,
129
+ zone_id,
130
+ enable_redirection,
122
131
  )
123
132
  session.__hosts = []
124
133
  session.__ports = []
@@ -181,12 +190,15 @@ class Session(object):
181
190
  else:
182
191
  client = Client(TBinaryProtocol.TBinaryProtocolAccelerated(transport))
183
192
 
193
+ configuration = {"version": "V_1_0", "sql_dialect": self.sql_dialect}
194
+ if self.database is not None:
195
+ configuration["db"] = self.database
184
196
  open_req = TSOpenSessionReq(
185
197
  client_protocol=self.protocol_version,
186
198
  username=self.__user,
187
199
  password=self.__password,
188
200
  zoneId=self.__zone_id,
189
- configuration={"version": "V_1_0"},
201
+ configuration=configuration,
190
202
  )
191
203
 
192
204
  try:
@@ -498,6 +510,15 @@ class Session(object):
498
510
  string_values = [string_values]
499
511
  if type(measurements) == str:
500
512
  measurements = [measurements]
513
+ if self.__has_none_value(string_values):
514
+ filtered_measurements, filtered_values = zip(
515
+ *[(m, v) for m, v in zip(measurements, string_values) if v is not None]
516
+ )
517
+ measurements = list(filtered_measurements)
518
+ values = list(filtered_values)
519
+ if len(measurements) == 0 or len(values) == 0:
520
+ logger.info("All inserting values are none!")
521
+ return
501
522
  request = self.gen_insert_str_record_req(
502
523
  device_id, timestamp, measurements, string_values
503
524
  )
@@ -529,6 +550,15 @@ class Session(object):
529
550
  string_values = [string_values]
530
551
  if type(measurements) == str:
531
552
  measurements = [measurements]
553
+ if self.__has_none_value(string_values):
554
+ filtered_measurements, filtered_values = zip(
555
+ *[(m, v) for m, v in zip(measurements, string_values) if v is not None]
556
+ )
557
+ measurements = list(filtered_measurements)
558
+ values = list(filtered_values)
559
+ if len(measurements) == 0 or len(values) == 0:
560
+ logger.info("All inserting values are none!")
561
+ return
532
562
  request = self.gen_insert_str_record_req(
533
563
  device_id, timestamp, measurements, string_values, True
534
564
  )
@@ -564,6 +594,20 @@ class Session(object):
564
594
  :param data_types: List of TSDataType, indicate the data type for each sensor
565
595
  :param values: List, values to be inserted, for each sensor
566
596
  """
597
+ if self.__has_none_value(values):
598
+ filtered_measurements, filtered_data_types, filtered_values = zip(
599
+ *[
600
+ (m, d, v)
601
+ for m, d, v in zip(measurements, data_types, values)
602
+ if v is not None
603
+ ]
604
+ )
605
+ measurements = list(filtered_measurements)
606
+ data_types = list(filtered_data_types)
607
+ values = list(filtered_values)
608
+ if len(measurements) == 0 or len(data_types) == 0 or len(values) == 0:
609
+ logger.info("All inserting values are none!")
610
+ return
567
611
  request = self.gen_insert_record_req(
568
612
  device_id, timestamp, measurements, data_types, values
569
613
  )
@@ -597,6 +641,19 @@ class Session(object):
597
641
  :param types_lst: 2-D List of TSDataType, each element of outer list indicates sensor data types of a device
598
642
  :param values_lst: 2-D List, values to be inserted, for each device
599
643
  """
644
+ if self.__has_none_value(values_lst):
645
+ (
646
+ device_ids,
647
+ times,
648
+ measurements_lst,
649
+ types_lst,
650
+ values_lst,
651
+ ) = self.__filter_lists_by_values(
652
+ device_ids, times, measurements_lst, types_lst, values_lst
653
+ )
654
+ if len(device_ids) == 0:
655
+ logger.info("All inserting values are none!")
656
+ return
600
657
  if self.__enable_redirection:
601
658
  request_group = {}
602
659
  for i in range(len(device_ids)):
@@ -666,6 +723,20 @@ class Session(object):
666
723
  :param data_types: List of TSDataType, indicate the data type for each sensor
667
724
  :param values: List, values to be inserted, for each sensor
668
725
  """
726
+ if self.__has_none_value(values):
727
+ filtered_measurements, filtered_data_types, filtered_values = zip(
728
+ *[
729
+ (m, d, v)
730
+ for m, d, v in zip(measurements, data_types, values)
731
+ if v is not None
732
+ ]
733
+ )
734
+ measurements = list(filtered_measurements)
735
+ data_types = list(filtered_data_types)
736
+ values = list(filtered_values)
737
+ if len(measurements) == 0 or len(data_types) == 0 or len(values) == 0:
738
+ logger.info("All inserting values are none!")
739
+ return
669
740
  request = self.gen_insert_record_req(
670
741
  device_id, timestamp, measurements, data_types, values, True
671
742
  )
@@ -699,6 +770,19 @@ class Session(object):
699
770
  :param types_lst: 2-D List of TSDataType, each element of outer list indicates sensor data types of a device
700
771
  :param values_lst: 2-D List, values to be inserted, for each device
701
772
  """
773
+ if self.__has_none_value(values_lst):
774
+ (
775
+ device_ids,
776
+ times,
777
+ measurements_lst,
778
+ types_lst,
779
+ values_lst,
780
+ ) = self.__filter_lists_by_values(
781
+ device_ids, times, measurements_lst, types_lst, values_lst
782
+ )
783
+ if len(device_ids) == 0:
784
+ logger.info("All inserting values are none!")
785
+ return
702
786
  if self.__enable_redirection:
703
787
  request_group = {}
704
788
  for i in range(len(device_ids)):
@@ -891,13 +975,15 @@ class Session(object):
891
975
  """
892
976
  request = self.gen_insert_tablet_req(tablet)
893
977
  try:
894
- connection = self.get_connection(tablet.get_device_id())
978
+ connection = self.get_connection(tablet.get_insert_target_name())
895
979
  request.sessionId = connection.session_id
896
980
  return Session.verify_success_with_redirection(
897
981
  connection.client.insertTablet(request)
898
982
  )
899
983
  except RedirectException as e:
900
- return self.handle_redirection(tablet.get_device_id(), e.redirect_node)
984
+ return self.handle_redirection(
985
+ tablet.get_insert_target_name(), e.redirect_node
986
+ )
901
987
  except TTransport.TException as e:
902
988
  if self.reconnect():
903
989
  try:
@@ -916,14 +1002,14 @@ class Session(object):
916
1002
  if self.__enable_redirection:
917
1003
  request_group = {}
918
1004
  for i in range(len(tablet_lst)):
919
- connection = self.get_connection(tablet_lst[i].get_device_id())
1005
+ connection = self.get_connection(tablet_lst[i].get_insert_target_name())
920
1006
  request = request_group.setdefault(
921
1007
  connection.client,
922
1008
  TSInsertTabletsReq(
923
1009
  connection.session_id, [], [], [], [], [], [], False
924
1010
  ),
925
1011
  )
926
- request.prefixPaths.append(tablet_lst[i].get_device_id())
1012
+ request.prefixPaths.append(tablet_lst[i].get_insert_target_name())
927
1013
  request.timestampsList.append(tablet_lst[i].get_binary_timestamps())
928
1014
  request.measurementsList.append(tablet_lst[i].get_measurements())
929
1015
  request.valuesList.append(tablet_lst[i].get_binary_values())
@@ -982,13 +1068,15 @@ class Session(object):
982
1068
  """
983
1069
  request = self.gen_insert_tablet_req(tablet, True)
984
1070
  try:
985
- connection = self.get_connection(tablet.get_device_id())
1071
+ connection = self.get_connection(tablet.get_insert_target_name())
986
1072
  request.sessionId = connection.session_id
987
1073
  return Session.verify_success_with_redirection(
988
1074
  connection.client.insertTablet(request)
989
1075
  )
990
1076
  except RedirectException as e:
991
- return self.handle_redirection(tablet.get_device_id(), e.redirect_node)
1077
+ return self.handle_redirection(
1078
+ tablet.get_insert_target_name(), e.redirect_node
1079
+ )
992
1080
  except TTransport.TException as e:
993
1081
  if self.reconnect():
994
1082
  try:
@@ -1007,14 +1095,14 @@ class Session(object):
1007
1095
  if self.__enable_redirection:
1008
1096
  request_group = {}
1009
1097
  for i in range(len(tablet_lst)):
1010
- connection = self.get_connection(tablet_lst[i].get_device_id())
1098
+ connection = self.get_connection(tablet_lst[i].get_insert_target_name())
1011
1099
  request = request_group.setdefault(
1012
1100
  connection.client,
1013
1101
  TSInsertTabletsReq(
1014
1102
  connection.session_id, [], [], [], [], [], [], True
1015
1103
  ),
1016
1104
  )
1017
- request.prefixPaths.append(tablet_lst[i].get_device_id())
1105
+ request.prefixPaths.append(tablet_lst[i].get_insert_target_name())
1018
1106
  request.timestampsList.append(tablet_lst[i].get_binary_timestamps())
1019
1107
  request.measurementsList.append(tablet_lst[i].get_measurements())
1020
1108
  request.valuesList.append(tablet_lst[i].get_binary_values())
@@ -1059,6 +1147,36 @@ class Session(object):
1059
1147
  self.connection_error_msg()
1060
1148
  ) from None
1061
1149
 
1150
+ def insert_relational_tablet(self, tablet):
1151
+ """
1152
+ insert one tablet, for example three column in the table1 can form a tablet:
1153
+ timestamps, id1, attr1, m1
1154
+ 1, id:1, attr:1, 1.0
1155
+ 2, id:1, attr:1, 2.0
1156
+ 3, id:2, attr:2, 3.0
1157
+ :param tablet: a tablet specified above
1158
+ """
1159
+ request = self.gen_insert_relational_tablet_req(tablet)
1160
+ try:
1161
+ connection = self.get_connection(tablet.get_insert_target_name())
1162
+ request.sessionId = connection.session_id
1163
+ return Session.verify_success_with_redirection(
1164
+ connection.client.insertTablet(request)
1165
+ )
1166
+ except RedirectException as e:
1167
+ return self.handle_redirection(
1168
+ tablet.get_insert_target_name(), e.redirect_node
1169
+ )
1170
+ except TTransport.TException as e:
1171
+ if self.reconnect():
1172
+ try:
1173
+ request.sessionId = self.__session_id
1174
+ return Session.verify_success(self.__client.insertTablet(request))
1175
+ except TTransport.TException as e1:
1176
+ raise IoTDBConnectionException(e1) from None
1177
+ else:
1178
+ raise IoTDBConnectionException(self.connection_error_msg()) from None
1179
+
1062
1180
  def insert_records_of_one_device(
1063
1181
  self, device_id, times_list, measurements_list, types_list, values_list
1064
1182
  ):
@@ -1275,13 +1393,27 @@ class Session(object):
1275
1393
  def gen_insert_tablet_req(self, tablet, is_aligned=False):
1276
1394
  return TSInsertTabletReq(
1277
1395
  self.__session_id,
1278
- tablet.get_device_id(),
1396
+ tablet.get_insert_target_name(),
1397
+ tablet.get_measurements(),
1398
+ tablet.get_binary_values(),
1399
+ tablet.get_binary_timestamps(),
1400
+ tablet.get_data_types(),
1401
+ tablet.get_row_number(),
1402
+ is_aligned,
1403
+ )
1404
+
1405
+ def gen_insert_relational_tablet_req(self, tablet, is_aligned=False):
1406
+ return TSInsertTabletReq(
1407
+ self.__session_id,
1408
+ tablet.get_insert_target_name(),
1279
1409
  tablet.get_measurements(),
1280
1410
  tablet.get_binary_values(),
1281
1411
  tablet.get_binary_timestamps(),
1282
1412
  tablet.get_data_types(),
1283
1413
  tablet.get_row_number(),
1284
1414
  is_aligned,
1415
+ True,
1416
+ tablet.get_column_categories(),
1285
1417
  )
1286
1418
 
1287
1419
  def gen_insert_tablets_req(self, tablet_lst, is_aligned=False):
@@ -1292,7 +1424,7 @@ class Session(object):
1292
1424
  type_lst = []
1293
1425
  size_lst = []
1294
1426
  for tablet in tablet_lst:
1295
- device_id_lst.append(tablet.get_device_id())
1427
+ device_id_lst.append(tablet.get_insert_target_name())
1296
1428
  measurements_lst.append(tablet.get_measurements())
1297
1429
  values_lst.append(tablet.get_binary_values())
1298
1430
  timestamps_lst.append(tablet.get_binary_timestamps())
@@ -1365,6 +1497,18 @@ class Session(object):
1365
1497
  else:
1366
1498
  raise IoTDBConnectionException(self.connection_error_msg()) from None
1367
1499
 
1500
+ previous_db = self.database
1501
+ if resp.database is not None:
1502
+ self.database = resp.database
1503
+ if previous_db != self.database and self.__endpoint_to_connection is not None:
1504
+ iterator = iter(self.__endpoint_to_connection.items())
1505
+ for entry in list(iterator):
1506
+ endpoint, connection = entry
1507
+ if connection != self.__default_connection:
1508
+ try:
1509
+ connection.change_database(sql)
1510
+ except Exception as e:
1511
+ self.__endpoint_to_connection.pop(endpoint)
1368
1512
  return Session.verify_success(resp.status)
1369
1513
 
1370
1514
  def execute_statement(self, sql: str, timeout=0):
@@ -1526,7 +1670,7 @@ class Session(object):
1526
1670
  ):
1527
1671
  return 0
1528
1672
 
1529
- raise RuntimeError(str(status.code) + ": " + status.message)
1673
+ raise RuntimeError(f"{status.code}: {status.message}")
1530
1674
 
1531
1675
  @staticmethod
1532
1676
  def verify_success_by_list(status_list: list):
@@ -1534,14 +1678,15 @@ class Session(object):
1534
1678
  verify success of operation
1535
1679
  :param status_list: execution result status
1536
1680
  """
1537
- message = str(Session.MULTIPLE_ERROR) + ": "
1538
- for status in status_list:
1539
- if (
1540
- status.code != Session.SUCCESS_STATUS
1541
- and status.code != Session.REDIRECTION_RECOMMEND
1542
- ):
1543
- message += status.message + "; "
1544
- raise RuntimeError(message)
1681
+ error_messages = [
1682
+ status.message
1683
+ for status in status_list
1684
+ if status.code
1685
+ not in {Session.SUCCESS_STATUS, Session.REDIRECTION_RECOMMEND}
1686
+ ]
1687
+ if error_messages:
1688
+ message = f"{Session.MULTIPLE_ERROR}: {'; '.join(error_messages)}"
1689
+ raise RuntimeError(message)
1545
1690
 
1546
1691
  @staticmethod
1547
1692
  def verify_success_with_redirection(status: TSStatus):
@@ -1842,6 +1987,49 @@ class Session(object):
1842
1987
  )
1843
1988
  return request
1844
1989
 
1990
+ def __has_none_value(self, values_list) -> bool:
1991
+ for item in values_list:
1992
+ if isinstance(item, list):
1993
+ if self.__has_none_value(item):
1994
+ return True
1995
+ elif item is None:
1996
+ return True
1997
+ return False
1998
+
1999
+ @staticmethod
2000
+ def __filter_lists_by_values(
2001
+ device_lst, time_lst, measurements_lst, types_lst, values_lst
2002
+ ):
2003
+ filtered_devices = []
2004
+ filtered_times = []
2005
+ filtered_measurements = []
2006
+ filtered_types = []
2007
+ filtered_values = []
2008
+
2009
+ for device, time_, measurements, types, values in zip(
2010
+ device_lst, time_lst, measurements_lst, types_lst, values_lst
2011
+ ):
2012
+ filtered_row = [
2013
+ (m, t, v)
2014
+ for m, t, v in zip(measurements, types, values)
2015
+ if v is not None
2016
+ ]
2017
+ if filtered_row:
2018
+ f_measurements, f_types, f_values = zip(*filtered_row)
2019
+ filtered_measurements.append(list(f_measurements))
2020
+ filtered_types.append(list(f_types))
2021
+ filtered_values.append(list(f_values))
2022
+ filtered_devices.append(device)
2023
+ filtered_times.append(time_)
2024
+
2025
+ return (
2026
+ filtered_devices,
2027
+ filtered_times,
2028
+ filtered_measurements,
2029
+ filtered_types,
2030
+ filtered_values,
2031
+ )
2032
+
1845
2033
  def create_schema_template(self, template: Template):
1846
2034
  warnings.warn(
1847
2035
  "The APIs about template are deprecated and will be removed in future versions. Use sql instead.",
@@ -2253,6 +2441,17 @@ class SessionConnection(object):
2253
2441
  self.session_id = session_id
2254
2442
  self.statement_id = statement_id
2255
2443
 
2444
+ def change_database(self, sql):
2445
+ try:
2446
+ self.client.executeUpdateStatement(
2447
+ TSExecuteStatementReq(self.session_id, sql, self.statement_id)
2448
+ )
2449
+ except TTransport.TException as e:
2450
+ raise IoTDBConnectionException(
2451
+ "failed to change database",
2452
+ e,
2453
+ ) from None
2454
+
2256
2455
  def close_connection(self, req):
2257
2456
  try:
2258
2457
  self.client.closeSession(req)
@@ -27,6 +27,7 @@ DEFAULT_MULTIPIE = 5
27
27
  DEFAULT_FETCH_SIZE = 5000
28
28
  DEFAULT_MAX_RETRY = 3
29
29
  DEFAULT_TIME_ZONE = "UTC+8"
30
+ SQL_DIALECT = "tree"
30
31
  logger = logging.getLogger("IoTDB")
31
32
 
32
33
 
@@ -42,6 +43,7 @@ class PoolConfig(object):
42
43
  time_zone: str = DEFAULT_TIME_ZONE,
43
44
  max_retry: int = DEFAULT_MAX_RETRY,
44
45
  enable_compression: bool = False,
46
+ enable_redirection: bool = True,
45
47
  ):
46
48
  self.host = host
47
49
  self.port = port
@@ -58,6 +60,7 @@ class PoolConfig(object):
58
60
  self.time_zone = time_zone
59
61
  self.max_retry = max_retry
60
62
  self.enable_compression = enable_compression
63
+ self.enable_redirection = enable_redirection
61
64
 
62
65
 
63
66
  class SessionPool(object):
@@ -71,6 +74,8 @@ class SessionPool(object):
71
74
  self.__queue = Queue(max_pool_size)
72
75
  self.__lock = Lock()
73
76
  self.__closed = False
77
+ self.sql_dialect = SQL_DIALECT
78
+ self.database = None
74
79
 
75
80
  def __construct_session(self) -> Session:
76
81
  if len(self.__pool_config.node_urls) > 0:
@@ -80,7 +85,10 @@ class SessionPool(object):
80
85
  self.__pool_config.password,
81
86
  self.__pool_config.fetch_size,
82
87
  self.__pool_config.time_zone,
88
+ enable_redirection=self.__pool_config.enable_redirection,
83
89
  )
90
+ session.sql_dialect = self.sql_dialect
91
+ session.database = self.database
84
92
 
85
93
  else:
86
94
  session = Session(
@@ -90,7 +98,10 @@ class SessionPool(object):
90
98
  self.__pool_config.password,
91
99
  self.__pool_config.fetch_size,
92
100
  self.__pool_config.time_zone,
101
+ enable_redirection=self.__pool_config.enable_redirection,
93
102
  )
103
+ session.sql_dialect = self.sql_dialect
104
+ session.database = self.database
94
105
 
95
106
  session.open(self.__pool_config.enable_compression)
96
107
  return session
@@ -18,13 +18,14 @@
18
18
 
19
19
  from sqlalchemy import types, util
20
20
  from sqlalchemy.engine import default
21
+ from sqlalchemy.sql import text
21
22
  from sqlalchemy.sql.sqltypes import String
22
23
 
23
24
  from iotdb import dbapi
24
25
 
26
+ from .IoTDBIdentifierPreparer import IoTDBIdentifierPreparer
25
27
  from .IoTDBSQLCompiler import IoTDBSQLCompiler
26
28
  from .IoTDBTypeCompiler import IoTDBTypeCompiler
27
- from .IoTDBIdentifierPreparer import IoTDBIdentifierPreparer
28
29
 
29
30
  TYPES_MAP = {
30
31
  "BOOLEAN": types.Boolean,
@@ -68,6 +69,10 @@ class IoTDBDialect(default.DefaultDialect):
68
69
  opts.update({"sqlalchemy_mode": True})
69
70
  return [[], opts]
70
71
 
72
+ @classmethod
73
+ def import_dbapi(cls):
74
+ return dbapi
75
+
71
76
  @classmethod
72
77
  def dbapi(cls):
73
78
  return dbapi
@@ -79,17 +84,19 @@ class IoTDBDialect(default.DefaultDialect):
79
84
  return table_name in self.get_table_names(connection, schema=schema)
80
85
 
81
86
  def get_schema_names(self, connection, **kw):
82
- cursor = connection.execute("SHOW DATABASES")
87
+ cursor = connection.execute(text("SHOW DATABASES"))
83
88
  return [row[0] for row in cursor.fetchall()]
84
89
 
85
90
  def get_table_names(self, connection, schema=None, **kw):
86
91
  cursor = connection.execute(
87
- "SHOW DEVICES %s.**" % (schema or self.default_schema_name)
92
+ text("SHOW DEVICES %s.**" % (schema or self.default_schema_name))
88
93
  )
89
94
  return [row[0].replace(schema + ".", "", 1) for row in cursor.fetchall()]
90
95
 
91
96
  def get_columns(self, connection, table_name, schema=None, **kw):
92
- cursor = connection.execute("SHOW TIMESERIES %s.%s.*" % (schema, table_name))
97
+ cursor = connection.execute(
98
+ text("SHOW TIMESERIES %s.%s.*" % (schema, table_name))
99
+ )
93
100
  columns = [self._general_time_column_info()]
94
101
  for row in cursor.fetchall():
95
102
  columns.append(self._create_column_info(row, schema, table_name))