As other people have commented, the process seems to be:
- Load all the points you wish to change to local memory.
- Change all these points.
- Upload them back to influx.
- Delete the old values.
I wrote some helper functions in python today to do this for me, which I though I could share. The solution is a bit bulky, but I had most of the functions from before. I am sure there are other more concise ways, but I could not find a full python example, so here is mine:
Main function:
def replace_tag(database_name:str, measurement_name:str, tag:str, old_value:str, new_value:str,):
""" Replaces an existing tag into a measurement, with a new tag for all affected records by deleting and reuploading """
q = 'SELECT * FROM "'+ measurement_name + '"' + ' WHERE "' + tag + '" = ' + "'" + old_value + "'"
df = influx_get_read_query(query=q, database_name=database_name)
print(df)
tags_keys = influx_get_tag_keys(database_name=database_name)
field_keys = influx_get_field_keys(database_name=database_name, measurement_name=measurement_name)
new_points = []
for i in trange(0, len(df)):
row = df.iloc[i]
print('row:', i)
row_dict = row.to_dict()
print('old row dict:', row_dict)
new_tags = {}
new_fields = {}
new_time = ''
for key in row_dict.keys():
if key in tags_keys:
new_tags[key] = row_dict[key]
elif key in field_keys:
new_fields[key] = row_dict[key]
elif key == 'time':
new_time = row_dict[key]
else:
easygui.msgbox('WARNING: A KEY WAS NOT FOUND: ' + str(key))
new_tags[tag] = new_value
new_row_dict = {}
new_row_dict['measurement'] = measurement_name
new_row_dict['tags'] = new_tags
new_row_dict['time'] = new_time
new_row_dict['fields'] = new_fields
new_points.append(new_row_dict)
influx_write_multiple_dicts(data_dicts=new_points, database_name=database_name)
influx_delete_series(database_name=database_name, measurement_name=measurement_name, tag=tag, tag_value=old_value)
Other helper funnctions:
def influx_delete_series(database_name, measurement_name, tag, tag_value):
q = 'DROP SERIES FROM "' + measurement_name + '"' + ' WHERE "' + tag + '" = ' + "'" + tag_value + "'"
client = InfluxDBClient(host=HOST_ADDRESS, port=PORT, username="InfluxDB", password="Influx-DB-PASSWORD")
client.switch_database(database_name)
client.query(q, chunked=True, chunk_size=10000000000000000)
def influx_write_multiple_dicts(data_dicts:list, database_name):
"""Write a list of dicts with following structure:
database_output_influx['measurement'] = 'SENSOR_ELEMENT_SUMMARY_TEST2'
database_output_influx['tags'] = {'serialNumber':'1234', 'partNumber':'5678'}
d = datetime.now()
timestamp = d.isoformat('T')
database_output_influx['time'] = timestamp
database_output_influx['fields'] = summary_results_dict
"""
client = InfluxDBClient(host=HOST_ADDRESS, port=PORT, username="InfluxDB", password="Influx-DB-PASSWORD")
client.switch_database(database_name)
print("Return code for influx write:", client.write_points(data_dicts))
def influx_get_tag_keys(database_name):
client = InfluxDBClient(host=HOST_ADDRESS, port=PORT, username="InfluxDB", password="Influx-DB-PASSWORD")
client.switch_database(database_name)
results = client.query("SHOW TAG KEYS ")
point_list = []
points = results.get_points()
for point in points:
point_list.append(point['tagKey'])
return point_list
def influx_get_field_keys(measurement_name, database_name):
client = InfluxDBClient(host=HOST_ADDRESS, port=PORT, username="InfluxDB", password="Influx-DB-PASSWORD")
client.switch_database(database_name)
results = client.query("SHOW FIELD KEYS FROM " + measurement_name)
point_list = []
points = results.get_points()
for point in points:
point_list.append(point['fieldKey'])
return point_list
def influx_get_read_query(query, database_name):
"""Returns a df of all measurements that have a certain field or value, for example stage. Note: single quotes for tag values, double quotes for al else. So best to use triple quotes surrounding statement. example:"""
client = InfluxDBClient(host=HOST_ADDRESS, port=PORT, username="InfluxDB", password="Influx-DB-PASSWORD")
client.switch_database(database_name)
q = query
df = pd.DataFrame(client.query(q, chunked=True, chunk_size=10000000000000000).get_points())
return df