8000 feat: CSV parser is able to parse export from UI (#171) · gain620/influxdb-client-python@25626c7 · GitHub
[go: up one dir, main page]

Skip to content

Commit 25626c7

Browse files
authored
feat: CSV parser is able to parse export from UI (influxdata#171)
1 parent ffae906 commit 25626c7

File tree

3 files changed

+34
-7
lines changed

3 files changed

+34
-7
lines changed

CHANGELOG.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
## 1.13.0 [unreleased]
22

3-
### Bug Fixes
4-
1. [#164](https://github.com/influxdata/influxdb-client-python/pull/170): Skip DataFrame rows without data - all fields are nan.
3+
### Features
4+
1. [#171](https://github.com/influxdata/influxdb-client-python/pull/171): CSV parser is able to parse export from UI
55

6+
### Bug Fixes
7+
1. [#170](https://github.com/influxdata/influxdb-client-python/pull/170): Skip DataFrame rows without data - all fields are nan.
68

79
## 1.12.0 [2020-10-30]
810

influxdb_client/client/flux_csv_parser.py

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,12 @@
1313
from influxdb_client.client.flux_table import FluxTable, FluxColumn, FluxRecord
1414

1515

16+
ANNOTATION_DEFAULT = "#default"
17+
ANNOTATION_GROUP = "#group"
18+
ANNOTATION_DATATYPE = "#datatype"
19+
ANNOTATIONS = [ANNOTATION_DEFAULT, ANNOTATION_GROUP, ANNOTATION_DATATYPE]
20+
21+
1622
class FluxQueryException(Exception):
1723
"""The exception from InfluxDB."""
1824

@@ -68,6 +74,7 @@ def _parse_flux_response(self):
6874
table_id = -1
6975
start_new_table = False
7076
table = None
77+
groups = []
7178
parsing_state_error = False
7279

7380
for csv in self._reader:
@@ -90,7 +97,7 @@ def _parse_flux_response(self):
9097

9198
token = csv[0]
9299
# start new table
93-
if "#datatype" == token:
100+
if token in ANNOTATIONS and not start_new_table:
94101

95102
# Return already parsed DataFrame
96103
if (self._serialization_mode is FluxSerializationMode.dataFrame) & hasattr(self, '_data_frame'):
@@ -105,18 +112,19 @@ def _parse_flux_response(self):
105112
raise FluxCsvParserException("Unable to parse CSV response. FluxTable definition was not found.")
106113

107114
# # datatype,string,long,dateTime:RFC3339,dateTime:RFC3339,dateTime:RFC3339,double,string,string,string
108-
if "#datatype" == token:
115+
if ANNOTATION_DATATYPE == token:
109116
self.add_data_types(table, csv)
110117

111-
elif "#group" == token:
112-
self.add_groups(table, csv)
118+
elif ANNOTATION_GROUP == token:
119+
groups = csv
113120

114-
elif "#default" == token:
121+
elif ANNOTATION_DEFAULT == token:
115122
self.add_default_empty_values(table, csv)
116123

117124
else:
118125
# parse column names
119126
if start_new_table:
127+
self.add_groups(table, groups)
120128
self.add_column_names_and_tags(table, csv)
121129
start_new_table = False
122130
# Create DataFrame with default values

tests/test_FluxCSVParser.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,23 @@ def test_response_with_error(self):
141141
self.assertEqual('engine: unknown field type for value: xyz', exception.message)
142142
self.assertEqual('', exception.reference)
143143

144+
def test_ParseExportFromUserInterface(self):
145+
146+
data = "#group,false,false,true,true,true,true,true,true,false,false\n" \
147+
+ "#datatype,string,long,dateTime:RFC3339,dateTime:RFC3339,string,string,string,string,double,dateTime:RFC3339\n" \
148+
+ "#default,mean,,,,,,,,,\n" \
149+
+ ",result,table,_start,_stop,_field,_measurement,city,location,_value,_time\n" \
150+
+ ",,0,1754-06-26T11:30:27.613654848Z,2040-10-27T12:13:46.485Z,temperatureC,weather,London,us-midwest,30,1975-09-01T16:59:54.5Z\n" \
151+
+ ",,1,1754-06-26T11:30:27.613654848Z,2040-10-27T12:13:46.485Z,temperatureF,weather,London,us-midwest,86,1975-09-01T16:59:54.5Z\n";
152+
153+
tables = self._parse_to_tables(data=data)
154+
self.assertEqual(2, tables.__len__())
155+
self.assertEqual(1, tables[0].records.__len__())
156+
self.assertEqual(1, tables[1].records.__len__())
157+
self.assertFalse(tables[1].columns[0].group)
158+
self.assertFalse(tables[1].columns[1].group)
159+
self.assertTrue(tables[1].columns[2].group)
160+
144161
@staticmethod
145162
def _parse_to_tables(data: str):
146163
fp = BytesIO(str.encode(data))

0 commit comments

Comments
 (0)
0