Skip to content
This repository was archived by the owner on Oct 29, 2024. It is now read-only.

Commit b0d7cdc

Browse files
authored
fix: Correctly serialize nanosecond dataframe timestamps (#926)
2 parents 5ad04f6 + b614474 commit b0d7cdc

File tree

2 files changed

+75
-3
lines changed

2 files changed

+75
-3
lines changed

influxdb/_dataframe_client.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -372,10 +372,10 @@ def _convert_dataframe_to_lines(self,
372372

373373
# Make array of timestamp ints
374374
if isinstance(dataframe.index, pd.PeriodIndex):
375-
time = ((dataframe.index.to_timestamp().values.astype(np.int64) /
375+
time = ((dataframe.index.to_timestamp().values.astype(np.int64) //
376376
precision_factor).astype(np.int64).astype(str))
377377
else:
378-
time = ((pd.to_datetime(dataframe.index).values.astype(np.int64) /
378+
time = ((pd.to_datetime(dataframe.index).values.astype(np.int64) //
379379
precision_factor).astype(np.int64).astype(str))
380380

381381
# If tag columns exist, make an array of formatted tag keys and values

influxdb/tests/dataframe_client_test.py

Lines changed: 73 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -877,7 +877,7 @@ def test_query_into_dataframe(self):
877877
{"measurement": "network",
878878
"tags": {"direction": ""},
879879
"columns": ["time", "value"],
880-
"values":[["2009-11-10T23:00:00Z", 23422]]
880+
"values": [["2009-11-10T23:00:00Z", 23422]]
881881
},
882882
{"measurement": "network",
883883
"tags": {"direction": "in"},
@@ -1274,3 +1274,75 @@ def test_query_custom_index(self):
12741274

12751275
self.assertListEqual(["time", "host"],
12761276
list(_data_frame.index.names))
1277+
1278+
def test_dataframe_nanosecond_precision(self):
1279+
"""Test nanosecond precision."""
1280+
for_df_dict = {
1281+
"nanFloats": [1.1, float('nan'), 3.3, 4.4],
1282+
"onlyFloats": [1.1, 2.2, 3.3, 4.4],
1283+
"strings": ['one_one', 'two_two', 'three_three', 'four_four']
1284+
}
1285+
df = pd.DataFrame.from_dict(for_df_dict)
1286+
df['time'] = ['2019-10-04 06:27:19.850557111+00:00',
1287+
'2019-10-04 06:27:19.850557184+00:00',
1288+
'2019-10-04 06:27:42.251396864+00:00',
1289+
'2019-10-04 06:27:42.251396974+00:00']
1290+
df['time'] = pd.to_datetime(df['time'], unit='ns')
1291+
df = df.set_index('time')
1292+
1293+
expected = (
1294+
b'foo nanFloats=1.1,onlyFloats=1.1,strings="one_one" 1570170439850557111\n' # noqa E501 line too long
1295+
b'foo onlyFloats=2.2,strings="two_two" 1570170439850557184\n' # noqa E501 line too long
1296+
b'foo nanFloats=3.3,onlyFloats=3.3,strings="three_three" 1570170462251396864\n' # noqa E501 line too long
1297+
b'foo nanFloats=4.4,onlyFloats=4.4,strings="four_four" 1570170462251396974\n' # noqa E501 line too long
1298+
)
1299+
1300+
with requests_mock.Mocker() as m:
1301+
m.register_uri(
1302+
requests_mock.POST,
1303+
"http://localhost:8086/write",
1304+
status_code=204
1305+
)
1306+
1307+
cli = DataFrameClient(database='db')
1308+
cli.write_points(df, 'foo', time_precision='n')
1309+
1310+
self.assertEqual(m.last_request.body, expected)
1311+
1312+
def test_dataframe_nanosecond_precision_one_microsecond(self):
1313+
"""Test nanosecond precision within one microsecond."""
1314+
# 1 microsecond = 1000 nanoseconds
1315+
start = np.datetime64('2019-10-04T06:27:19.850557000')
1316+
end = np.datetime64('2019-10-04T06:27:19.850558000')
1317+
1318+
# generate timestamps with nanosecond precision
1319+
timestamps = np.arange(
1320+
start,
1321+
end + np.timedelta64(1, 'ns'),
1322+
np.timedelta64(1, 'ns')
1323+
)
1324+
# generate values
1325+
values = np.arange(0.0, len(timestamps))
1326+
1327+
df = pd.DataFrame({'value': values}, index=timestamps)
1328+
with requests_mock.Mocker() as m:
1329+
m.register_uri(
1330+
requests_mock.POST,
1331+
"http://localhost:8086/write",
1332+
status_code=204
1333+
)
1334+
1335+
cli = DataFrameClient(database='db')
1336+
cli.write_points(df, 'foo', time_precision='n')
1337+
1338+
lines = m.last_request.body.decode('utf-8').split('\n')
1339+
self.assertEqual(len(lines), 1002)
1340+
1341+
for index, line in enumerate(lines):
1342+
if index == 1001:
1343+
self.assertEqual(line, '')
1344+
continue
1345+
self.assertEqual(
1346+
line,
1347+
f"foo value={index}.0 157017043985055{7000 + index:04}"
1348+
)

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy