Skip to content

Commit 89961cf

Browse files
xginn8aviau
authored andcommitted
Fix failing tags match in get_points() on a ResultSet (influxdata#511)
* rename serie to series * pass in tags variable to perform match fix the format of the object in the ResultSet test to match what's returned from a query fix other flake8 formatting issues * meh * more serie -> series * fixing broken tags filtering * readding missing parameter that i somehow dropped
1 parent 530b4c5 commit 89961cf

File tree

5 files changed

+118
-93
lines changed

5 files changed

+118
-93
lines changed

docs/source/resultset.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ Using ``rs.get_points()`` will return a generator for all the points in the Resu
1818
Filtering by measurement
1919
------------------------
2020

21-
Using ``rs.get_points('cpu')`` will return a generator for all the points that are in a serie with measurement name ``cpu``, no matter the tags.
21+
Using ``rs.get_points('cpu')`` will return a generator for all the points that are in a series with measurement name ``cpu``, no matter the tags.
2222
::
2323

2424
rs = cli.query("SELECT * from cpu")
@@ -36,7 +36,7 @@ Using ``rs.get_points(tags={'host_name': 'influxdb.com'})`` will return a genera
3636
Filtering by measurement and tags
3737
---------------------------------
3838

39-
Using measurement name and tags will return a generator for all the points that are in a serie with the specified measurement name AND whose tags match the given tags.
39+
Using measurement name and tags will return a generator for all the points that are in a series with the specified measurement name AND whose tags match the given tags.
4040
::
4141

4242
rs = cli.query("SELECT * from cpu")

influxdb/influxdb08/client.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -435,7 +435,7 @@ def _query(self, query, time_precision='s', chunked=False):
435435
else:
436436
chunked_param = 'false'
437437

438-
# Build the URL of the serie to query
438+
# Build the URL of the series to query
439439
url = "db/{0}/series".format(self._database)
440440

441441
params = {

influxdb/resultset.py

Lines changed: 35 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,12 @@ def error(self):
4141
def __getitem__(self, key):
4242
"""Retrieve the series name or specific set based on key.
4343
44-
:param key: Either a serie name, or a tags_dict, or
45-
a 2-tuple(serie_name, tags_dict).
46-
If the serie name is None (or not given) then any serie
44+
:param key: Either a series name, or a tags_dict, or
45+
a 2-tuple(series_name, tags_dict).
46+
If the series name is None (or not given) then any serie
4747
matching the eventual given tags will be given its points
4848
one after the other.
49-
To get the points of every serie in this resultset then
49+
To get the points of every series in this resultset then
5050
you have to provide None as key.
5151
:return: A generator yielding `Point`s matching the given key.
5252
NB:
@@ -93,22 +93,25 @@ def get_points(self, measurement=None, tags=None):
9393
(bytes, type(b''.decode()), type(None))):
9494
raise TypeError('measurement must be an str or None')
9595

96-
for serie in self._get_series():
97-
serie_name = serie.get('measurement', serie.get('name', 'results'))
98-
if serie_name is None:
96+
for series in self._get_series():
97+
series_name = series.get('measurement',
98+
series.get('name', 'results'))
99+
if series_name is None:
99100
# this is a "system" query or a query which
100101
# doesn't return a name attribute.
101102
# like 'show retention policies' ..
102103
if tags is None:
103-
for item in self._get_points_for_serie(serie):
104+
for item in self._get_points_for_series(series):
104105
yield item
105106

106-
elif measurement in (None, serie_name):
107+
elif measurement in (None, series_name):
107108
# by default if no tags was provided then
108-
# we will matches every returned serie
109-
serie_tags = serie.get('tags', {})
110-
if tags is None or self._tag_matches(serie_tags, tags):
111-
for item in self._get_points_for_serie(serie):
109+
# we will matches every returned series
110+
series_tags = series.get('tags', {})
111+
for item in self._get_points_for_series(series):
112+
if tags is None or \
113+
self._tag_matches(item, tags) or \
114+
self._tag_matches(series_tags, tags):
112115
yield item
113116

114117
def __repr__(self):
@@ -121,7 +124,7 @@ def __repr__(self):
121124
return "ResultSet({%s})" % ", ".join(items)
122125

123126
def __iter__(self):
124-
"""Yield one dict instance per serie result."""
127+
"""Yield one dict instance per series result."""
125128
for key in self.keys():
126129
yield list(self.__getitem__(key))
127130

@@ -131,10 +134,10 @@ def _tag_matches(tags, filter):
131134
for tag_name, tag_value in filter.items():
132135
# using _sentinel as I'm not sure that "None"
133136
# could be used, because it could be a valid
134-
# serie_tags value : when a serie has no such tag
137+
# series_tags value : when a series has no such tag
135138
# then I think it's set to /null/None/.. TBC..
136-
serie_tag_value = tags.get(tag_name, _sentinel)
137-
if serie_tag_value != tag_value:
139+
series_tag_value = tags.get(tag_name, _sentinel)
140+
if series_tag_value != tag_value:
138141
return False
139142

140143
return True
@@ -150,14 +153,14 @@ def __len__(self):
150153
def keys(self):
151154
"""Return the list of keys in the ResultSet.
152155
153-
:return: List of keys. Keys are tuples (serie_name, tags)
156+
:return: List of keys. Keys are tuples (series_name, tags)
154157
"""
155158
keys = []
156-
for serie in self._get_series():
159+
for series in self._get_series():
157160
keys.append(
158-
(serie.get('measurement',
159-
serie.get('name', 'results')),
160-
serie.get('tags', None))
161+
(series.get('measurement',
162+
series.get('name', 'results')),
163+
series.get('tags', None))
161164
)
162165
return keys
163166

@@ -167,24 +170,24 @@ def items(self):
167170
:return: List of tuples, (key, generator)
168171
"""
169172
items = []
170-
for serie in self._get_series():
171-
serie_key = (serie.get('measurement',
172-
serie.get('name', 'results')),
173-
serie.get('tags', None))
173+
for series in self._get_series():
174+
series_key = (series.get('measurement',
175+
series.get('name', 'results')),
176+
series.get('tags', None))
174177
items.append(
175-
(serie_key, self._get_points_for_serie(serie))
178+
(series_key, self._get_points_for_series(series))
176179
)
177180
return items
178181

179-
def _get_points_for_serie(self, serie):
180-
"""Return generator of dict from columns and values of a serie.
182+
def _get_points_for_series(self, series):
183+
"""Return generator of dict from columns and values of a series.
181184
182-
:param serie: One serie
185+
:param series: One series
183186
:return: Generator of dicts
184187
"""
185-
for point in serie.get('values', []):
188+
for point in series.get('values', []):
186189
yield self.point_from_cols_vals(
187-
serie['columns'],
190+
series['columns'],
188191
point
189192
)
190193

influxdb/tests/resultset_test.py

Lines changed: 63 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -19,26 +19,25 @@ def setUp(self):
1919
"""Set up an instance of TestResultSet."""
2020
self.query_response = {
2121
"results": [
22-
{"series": [{"measurement": "cpu_load_short",
23-
"tags": {"host": "server01",
24-
"region": "us-west"},
25-
"columns": ["time", "value"],
22+
{"series": [{"name": "cpu_load_short",
23+
"columns": ["time", "value", "host", "region"],
2624
"values": [
27-
["2015-01-29T21:51:28.968422294Z", 0.64]
25+
["2015-01-29T21:51:28.968422294Z",
26+
0.64,
27+
"server01",
28+
"us-west"],
29+
["2015-01-29T21:51:28.968422294Z",
30+
0.65,
31+
"server02",
32+
"us-west"],
2833
]},
29-
{"measurement": "cpu_load_short",
30-
"tags": {"host": "server02",
31-
"region": "us-west"},
32-
"columns": ["time", "value"],
34+
{"name": "other_series",
35+
"columns": ["time", "value", "host", "region"],
3336
"values": [
34-
["2015-01-29T21:51:28.968422294Z", 0.65]
35-
]},
36-
{"measurement": "other_serie",
37-
"tags": {"host": "server01",
38-
"region": "us-west"},
39-
"columns": ["time", "value"],
40-
"values": [
41-
["2015-01-29T21:51:28.968422294Z", 0.66]
37+
["2015-01-29T21:51:28.968422294Z",
38+
0.66,
39+
"server01",
40+
"us-west"],
4241
]}]}
4342
]
4443
}
@@ -48,8 +47,14 @@ def setUp(self):
4847
def test_filter_by_name(self):
4948
"""Test filtering by name in TestResultSet object."""
5049
expected = [
51-
{'value': 0.64, 'time': '2015-01-29T21:51:28.968422294Z'},
52-
{'value': 0.65, 'time': '2015-01-29T21:51:28.968422294Z'}
50+
{'value': 0.64,
51+
'time': '2015-01-29T21:51:28.968422294Z',
52+
'host': 'server01',
53+
'region': 'us-west'},
54+
{'value': 0.65,
55+
'time': '2015-01-29T21:51:28.968422294Z',
56+
'host': 'server02',
57+
'region': 'us-west'},
5358
]
5459

5560
self.assertEqual(expected, list(self.rs['cpu_load_short']))
@@ -60,8 +65,14 @@ def test_filter_by_name(self):
6065
def test_filter_by_tags(self):
6166
"""Test filter by tags in TestResultSet object."""
6267
expected = [
63-
{'time': '2015-01-29T21:51:28.968422294Z', 'value': 0.64},
64-
{'time': '2015-01-29T21:51:28.968422294Z', 'value': 0.66}
68+
{'value': 0.64,
69+
'time': '2015-01-29T21:51:28.968422294Z',
70+
'host': 'server01',
71+
'region': 'us-west'},
72+
{'value': 0.66,
73+
'time': '2015-01-29T21:51:28.968422294Z',
74+
'host': 'server01',
75+
'region': 'us-west'},
6576
]
6677

6778
self.assertEqual(
@@ -78,14 +89,23 @@ def test_filter_by_name_and_tags(self):
7889
"""Test filter by name and tags in TestResultSet object."""
7990
self.assertEqual(
8091
list(self.rs[('cpu_load_short', {"host": "server01"})]),
81-
[{'time': '2015-01-29T21:51:28.968422294Z', 'value': 0.64}]
92+
[{'value': 0.64,
93+
'time': '2015-01-29T21:51:28.968422294Z',
94+
'host': 'server01',
95+
'region': 'us-west'}]
8296
)
8397

8498
self.assertEqual(
8599
list(self.rs[('cpu_load_short', {"region": "us-west"})]),
86100
[
87-
{'value': 0.64, 'time': '2015-01-29T21:51:28.968422294Z'},
88-
{'value': 0.65, 'time': '2015-01-29T21:51:28.968422294Z'}
101+
{'value': 0.64,
102+
'time': '2015-01-29T21:51:28.968422294Z',
103+
'host': 'server01',
104+
'region': 'us-west'},
105+
{'value': 0.65,
106+
'time': '2015-01-29T21:51:28.968422294Z',
107+
'host': 'server02',
108+
'region': 'us-west'},
89109
]
90110
)
91111

@@ -94,17 +114,16 @@ def test_keys(self):
94114
self.assertEqual(
95115
self.rs.keys(),
96116
[
97-
('cpu_load_short', {'host': 'server01', 'region': 'us-west'}),
98-
('cpu_load_short', {'host': 'server02', 'region': 'us-west'}),
99-
('other_serie', {'host': 'server01', 'region': 'us-west'})
117+
('cpu_load_short', None),
118+
('other_series', None),
100119
]
101120
)
102121

103122
def test_len(self):
104123
"""Test length in TestResultSet object."""
105124
self.assertEqual(
106125
len(self.rs),
107-
3
126+
2
108127
)
109128

110129
def test_items(self):
@@ -116,21 +135,23 @@ def test_items(self):
116135
items_lists,
117136
[
118137
(
119-
('cpu_load_short',
120-
{'host': 'server01', 'region': 'us-west'}),
121-
[{'value': 0.64, 'time': '2015-01-29T21:51:28.968422294Z'}]
122-
),
138+
('cpu_load_short', None),
139+
[
140+
{'time': '2015-01-29T21:51:28.968422294Z',
141+
'value': 0.64,
142+
'host': 'server01',
143+
'region': 'us-west'},
144+
{'time': '2015-01-29T21:51:28.968422294Z',
145+
'value': 0.65,
146+
'host': 'server02',
147+
'region': 'us-west'}]),
123148
(
124-
('cpu_load_short',
125-
{'host': 'server02', 'region': 'us-west'}),
126-
[{'value': 0.65, 'time': '2015-01-29T21:51:28.968422294Z'}]
127-
),
128-
(
129-
('other_serie',
130-
{'host': 'server01', 'region': 'us-west'}),
131-
[{'value': 0.66, 'time': '2015-01-29T21:51:28.968422294Z'}]
132-
)
133-
]
149+
('other_series', None),
150+
[
151+
{'time': '2015-01-29T21:51:28.968422294Z',
152+
'value': 0.66,
153+
'host': 'server01',
154+
'region': 'us-west'}])]
134155
)
135156

136157
def test_point_from_cols_vals(self):

0 commit comments

Comments
 (0)