Skip to content

Commit

Permalink
feat: CSV parser is able to parse export from UI (#171)
Browse files Browse the repository at this point in the history
  • Loading branch information
bednar authored Nov 27, 2020
1 parent ffae906 commit 25626c7
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 7 deletions.
6 changes: 4 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
## 1.13.0 [unreleased]

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

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

## 1.12.0 [2020-10-30]

Expand Down
18 changes: 13 additions & 5 deletions influxdb_client/client/flux_csv_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@
from influxdb_client.client.flux_table import FluxTable, FluxColumn, FluxRecord


ANNOTATION_DEFAULT = "#default"
ANNOTATION_GROUP = "#group"
ANNOTATION_DATATYPE = "#datatype"
ANNOTATIONS = [ANNOTATION_DEFAULT, ANNOTATION_GROUP, ANNOTATION_DATATYPE]


class FluxQueryException(Exception):
"""The exception from InfluxDB."""

Expand Down Expand Up @@ -68,6 +74,7 @@ def _parse_flux_response(self):
table_id = -1
start_new_table = False
table = None
groups = []
parsing_state_error = False

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

token = csv[0]
# start new table
if "#datatype" == token:
if token in ANNOTATIONS and not start_new_table:

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

# # datatype,string,long,dateTime:RFC3339,dateTime:RFC3339,dateTime:RFC3339,double,string,string,string
if "#datatype" == token:
if ANNOTATION_DATATYPE == token:
self.add_data_types(table, csv)

elif "#group" == token:
self.add_groups(table, csv)
elif ANNOTATION_GROUP == token:
groups = csv

elif "#default" == token:
elif ANNOTATION_DEFAULT == token:
self.add_default_empty_values(table, csv)

else:
# parse column names
if start_new_table:
self.add_groups(table, groups)
self.add_column_names_and_tags(table, csv)
start_new_table = False
# Create DataFrame with default values
Expand Down
17 changes: 17 additions & 0 deletions tests/test_FluxCSVParser.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,23 @@ def test_response_with_error(self):
self.assertEqual('engine: unknown field type for value: xyz', exception.message)
self.assertEqual('', exception.reference)

def test_ParseExportFromUserInterface(self):

data = "#group,false,false,true,true,true,true,true,true,false,false\n" \
+ "#datatype,string,long,dateTime:RFC3339,dateTime:RFC3339,string,string,string,string,double,dateTime:RFC3339\n" \
+ "#default,mean,,,,,,,,,\n" \
+ ",result,table,_start,_stop,_field,_measurement,city,location,_value,_time\n" \
+ ",,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" \
+ ",,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";

tables = self._parse_to_tables(data=data)
self.assertEqual(2, tables.__len__())
self.assertEqual(1, tables[0].records.__len__())
self.assertEqual(1, tables[1].records.__len__())
self.assertFalse(tables[1].columns[0].group)
self.assertFalse(tables[1].columns[1].group)
self.assertTrue(tables[1].columns[2].group)

@staticmethod
def _parse_to_tables(data: str):
fp = BytesIO(str.encode(data))
Expand Down

0 comments on commit 25626c7

Please sign in to comment.