Skip to content

Commit b614474

Browse files
committed
fix: Correctly serialize nanosecond dataframe timestamps
Co-authored-by: @bednar
1 parent 915b79a commit b614474

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)