InfluxDBClientError partial write: field type conflict: is type float, already exists as type integer

I use a Python script to convert data from a database to a target database. Basically, the script works if the target database does not yet exist. However, the data should be transferred to an existing target database.
Then the following error message appears:

influxdb.exceptions.InfluxDBClientError: 400: {"error":"partial write: field type conflict: input field \"Netzbezug Leistung\" on measurement \"modbus\" is type float, already exists as type integer dropped=7586"}

With the command “show field keys from modbus” I get the information of the target database:

name: modbus
fieldKey           fieldType
--------           ---------
Netzbezug Leistung integer

The data generated with the script has the “fieldType: float”
How can I change the script so that the converted data is written in “fieldType: integer”?

#!/opt/bin/python3

from influxdb import InfluxDBClient

client = InfluxDBClient(host='192.168.xxx.xx', port=8086, username='admin', password='secret',database = 'homeassistant')

db_data = client.query(" select * FROM W WHERE entity_id = 'netzbezug_leistung_ksem' AND time >= now() - 1h ")

data_to_write = [
        {
            'measurement': 'modbus',
            'tags': {'host': 'telegraf', 'name': 'KSEM', 'slave_id': '1', 'type': 'holding_register'},
            'time': d['time'],
            'fields': {'Netzbezug Leistung': d['value']}
        }
        for d in db_data.get_points()
    ]

client.write_points(data_to_write, database='test', retention_policy='infinite')

I have almost 0 knowledge of Python and I’d expect the client to have some data type management function (I don’t know if that’s the case tho)

What I can tell you is the difference between float and integer when writing raw data (line protocol), values like 20 or 20.6 will usually be float, as that’s the assumed datatype for any numeric field. in order to write an integer it has to be specified by appending i to the value meaning that

20 → float
20i → integer

sample point
temperature sensor1 25i

1 Like

Hallo @Giovanni_Luisotto thank you very much for your quick answer. I had already found the solution you showed. But unfortunately I can’t use them in the Python script. Unfortunately, I also lack Python knowledge.
I might have another solution and I might need some help here as well.
The raw data stored in integers comes from the Telegraf collector.
Now I’m experimenting here with the “processors.converter.fields”. The data is hereby stored in “float”.

[[processors.converter]]
  [processors.converter.fields]
    float = [
      "Netzbezug Leistung",
      "Netzeinspeisung Leistung",
      "Netzbezug Energie",
      "Netzeinspeisung Energie"
    ]

This works very well!

However, I have much more than the 4 fields entered. I would definitely not have to pass about 30 more fields to the processor module so that they are then saved in “float”.
Now I can enter this line by line in the [processors.converter.fields] section.

Or could I somehow simplify it so that the complete database “modbus” is stored in “float”?

I can’t tell what’s the best case, you should be able to put simple float = ["*"], but what if you have string fields?

You can somehow simplify the creation of the specific list by querying the DB with a simple SHOW FIELD KEYS ON "__YourDB__" FROM "modbus" and use the result to quickly build the list… of course if any metric is added you will also need to add it in the config which is not that flexible

1 Like

Thanks, @Giovanni_Luisotto for your hint. In the case of Python-based InfluxDB client does not require field type to be declared explicitly. Anyway, the bash-based InfluxDB client requires the correct type of data.

import influxdb_client
from influxdb_client import InfluxDBClient, Point, WritePrecision
from influxdb_client.client.write_api import SYNCHRONOUS


token = ""
org = ""
url = "http://localhost:8086"
bucket=""
measurement = ""

write_client = influxdb_client.InfluxDBClient(url=url, token=token, org=org)
write_api = write_client.write_api(write_options=SYNCHRONOUS)

node, observed_at, fmt_observed_at = "", "", ""
current, voltage = 0, 0
power = round(voltage * current / 1000, 2)

try:
    point = (
      Point(measurement)
      .tag("by_node", node)
      .field("observed_at", observed_at)
      .field("fmt_observed_at", fmt_observed_at)
      .field("current", current)
      .field("voltage", voltage)
      .field("power", power)
    )
    
    write_api.write(bucket=bucket, org=org, record=point)

except KeyboardInterrupt:
    print("Closing the program!")
except Exception as e:
    print(e)

For the above code, I had to write bash code (i with integer values) as follows:

TOKEN=""
BUCKET=""
ORG=""
measurement=""

node="";
observed_at="";
fmt_observed_at="";
current=0;
voltage=0;

power=$(echo "scale=2; $voltage*$current/1000" | bc -l);

influx write \
    --org $ORG \
    --token $TOKEN \
    --bucket $BUCKET \
    "
    $measurement,by_node=$node observed_at=${observed_at}i,fmt_observed_at=\"$fmt_observed_at\",current=${current}i,voltage=${voltage}i,power=$power
    "