Documentation

Work with dynamic types

A dynamic type is a wrapper for data whose type is not known until runtime. Dynamic types help when working with data from external sources (like JSON) that support types that do not have an equivalent Flux type.

Dynamic types are not supported in tables

Dynamic types are not supported in Flux tables. To include a dynamic value in a Flux table, you must cast the dynamic type to a Flux basic type. For a full example of casting dynamic types to basic types and including them in a table, see Include dynamic types in a table.

Parse JSON into Flux types

The primary (but not exclusive) use case for dynamic types is converting JSON data into native Flux types; specifically Flux arrays and records.

Because of strict typing rules in Flux, JSON data doesn’t always gracefully parse into native Flux types. The most common reason is that Flux arrays require all children to be the same type. JSON arrays allow elements to be different types.

With Flux records (the corollary of a JSON object), the properties in the record are part of the record’s type. If you have a JSON array of objects where the objects’ schemas are different, the array cannot be parsed as a Flux array because the types of the records in the array do not match.

View examples of JSON arrays that cannot be directly parsed into Flux arrays

The dynamic type provides a way to resolve the differences between JSON and Flux types.

Dynamic type syntax

Flux does not provide a literal syntax for dynamic types. To cast a value to a dynamic type:

  1. Import the experimental/dynamic package.
  2. Use dynamic.dynamic() to convert a value to a dynamic type.
import "experimental/dynamic"

dynamic.dynamic(v: "Example string")

// Returns dynamic(Example string)

Reference values in a dynamic type

Use bracket and dot notation to reference values in dynamic records and arrays. Use the exists operator to check if a dynamic type contains a non-null value.

Reference values in a dynamic record

import "experimental/dynamic"

record = {one: 1, two: 2, three: 3}
dynamicRecord = dynamic.dynamic(v: record)

dynamicRecord.one
// Returns dynamic(1)

dynamicRecord["two"]
// Returns dynamic(2)

Reference values in a dynamic array

import "experimental/dynamic"

arr = ["a", "b", "c"]
dynamicArr = dynamic.asArray(v: dynamic.dynamic(v: arr))

dynamicArr[0]
// Returns dynamic(a)

Ensure a dynamic type contains a non-null value

Use the exists operator to check if a dynamic type contains a non-null value. If you attempt to access members of a null dynamic value, Flux returns an error. exists lets you guard against errors caused by attempting to access members in null dynamic values.

View examples of using exists to check for non-null dynamic types

Operate on dynamic types

Convert dynamic types to Flux types

Basic types

Use string() to convert a dynamic type to a string. string() returns the string representation of the dynamic value.

import "experimental/dynamic"

dynamicValue = dynamic.dynamic(v: "string")

string(v: dynamicValue)
// Returns "string"

Use int() to convert a dynamic type to an integer. int() returns the integer equivalent of the dynamic value.

import "experimental/dynamic"

dynamicValue = dynamic.dynamic(v: "12")

int(v: dynamicValue)
// Returns 12

Use uint() to convert a dynamic type to an unsigned integer (UInteger). uint() returns the UInteger equivalent of the dynamic value.

import "experimental/dynamic"

dynamicValue = dynamic.dynamic(v: "12")

uint(v: dynamicValue)
// Returns 12

Use float() to convert a dynamic type to a floating point value. float() returns the float equivalent of the dynamic value.

import "experimental/dynamic"

dynamicValue = dynamic.dynamic(v: "12.1")

float(v: dynamicValue)
// Returns 12.1

Use bool() to convert a dynamic type to a boolean value. bool() returns the boolean equivalent of the dynamic value.

import "experimental/dynamic"

dynamicValue = dynamic.dynamic(v: "true")

bool(v: dynamicValue)
// Returns true

Use duration() to convert a dynamic type to a duration value. duration() returns the duration equivalent of the dynamic value.

import "experimental/dynamic"

dynamicValue = dynamic.dynamic(v: 3000000000)

duration(v: dynamicValue)
// Returns 3s

Use time() to convert a dynamic type to a time value. time() returns the time equivalent of the dynamic value.

import "experimental/dynamic"

dynamicValue = dynamic.dynamic(v: 1640995200000000000)

time(v: dynamicValue)
// Returns 2022-01-01T00:00:00.000000000Z

Use bytes() to convert a dynamic type to a byte-encoded string. bytes() returns the bytes equivalent of the dynamic value.

import "experimental/dynamic"

dynamicValue = dynamic.dynamic(v: "Hello world!")

bytes(v: dynamicValue)
// Returns 0x48656c6c6f20776f726c6421
  1. Use string() to convert a dynamic type to a string.
  2. Import the regexp package and use regexp.compile() to convert the string value to a regular expression type.
import "experimental/dynamic"
import "regexp"

dynamicValue = dynamic.dynamic(v: "^[abc][123]{1,}")
stringValue = string(v: dynamicValue)

regexp.compile(v: stringValue)
// Returns /^[abc][123]{1,}/

Composite types

Dynamic composite types will almost always come from working with a byte-encoded JSON string. All the examples below assume this.

To convert a JSON array to a Flux array:

  1. Import the following packages:

  2. Use dynamic.jsonParse() to parse a byte-encoded JSON string into a dynamic type.

  3. Use dynamic.asArray() to convert the dynamic-typed array into an array of dynamic types.

  4. Use array.map() to iterate over each element in the array and explicitly cast dynamic types to basic types.

View example with an array of scalar values

View example with an array of JSON objects

To convert a JSON object to a Flux record:

  1. Import the experimental/dynamic package
  2. Use dynamic.jsonParse() to parse a byte-encoded JSON string into a dynamic type.
  3. Define a new record and cast each property of the dynamic type to a basic type.
JSON object
{"first-name": "John", "last-name": "Doe", "age": 42}
Convert a JSON object to a Flux record
import "experimental/dynamic"

json = jsonBytes // Byte-encoded JSON above
parsed = dynamic.jsonParse(data: json)

newRecord = {
    fname: string(v: parsed["first-name"]),
    lname: string(v: parsed["last-name"]),
    age: int(v: parsed.age)
}

// newRecord returns {age: 42, fname: John, lname: Doe}

Check the type of a value inside of a dynamic type

Use dynamic.isType() to check the type of a value inside of a dynamic type.

The following example uses the http/requests package and the Fruityvice API to return information about apples as a JSON object.

View the returned JSON object

import "experimental/dynamic"

response = requests.get(url: "https://www.fruityvice.com/api/fruit/apple")
parsed = dynamic.jsonParse(data: response.body)

dynamic.isType(v: parsed.genus, type: "string")
// Returns true

dynamic.isType(v: parsed.nutritions, type: "array")
// Returns false

dynamic.isType(v: parsed.nutritions, type: "object")
// Returns true

Include dynamic types in a table

Dynamic types are not supported in Flux tables. To include a dynamic value in a Flux table, cast the dynamic type to a Flux basic type.

The following example uses array.from() to build and ad hoc table using dynamic types. Each dynamic type must be cast to a Flux basic type when defining the row record.

import "array"
import "experimental/dynamic"

dynamicString = dynamic.dynamic(v: "one")
dynamicInt = dynamic.dynamic(v: 1)
dynamicFloat = dynamic.dynamic(v: 1.0)
dynamicBool = dynamic.dynamic(v: true)

array.from(
    rows: [
        {
            string: string(v: dynamicString),
            int: int(v: dynamicInt),
            float: float(v: dynamicFloat),
            bool: bool(v: dynamicBool),
        },
    ],
)

View output table

Convert a JSON array to a Flux table

  1. Import the following packages:

  2. Use dynamic.jsonParse() to parse the the JSON response body returned from requests.get() into a Flux dynamic type. Define a variable to capture the parsed JSON. The example below uses the parsed variable.

  3. Use dynamic.asArray() to convert the dynamic type returned by dynamic.jsonParse() to a dynamic array. Define a variable to capture the dynamic array. The example below uses the fruit variable.

  4. Use array.map() to do the following:

The following example uses the http/requests package and the Fruityvice API to return information about various fruit as JSON and then structure the returned data as a Flux table.

import "array"
import "experimental/dynamic"
import "http/requests"

response = requests.get(url: "https://www.fruityvice.com/api/fruit/all")
parsed = dynamic.jsonParse(data: response.body)
fruit = dynamic.asArray(v: parsed)

fruit_flat =
    fruit
        |> array.map(
            fn: (x) =>
                ({
                    name: string(v: x.name),
                    cals: int(v: x.nutritions.calories),
                    carbs: float(v: x.nutritions.carbohydrates),
                    fat: float(v: x.nutritions.fat),
                    protein: float(v: x.nutritions.protein),
                    sugar: float(v: x.nutritions.sugar),
                }),
        )

array.from(rows: fruit_flat)

View output table

Encode a dynamic type as JSON

Encode a dynamic record as JSON

  1. Import the experimental/dynamic package.
  2. Use dynamic.dynamic() to convert the record to a dynamic type.
  3. Use dynamic.jsonEncode() to convert the dynamic record into a byte-encoded JSON string.
import "experimental/dynamic"

dynamicRecord = dynamic.dynamic(v: {one: 1, two: 2, three: 3})

dynamic.jsonEncode(v: dynamicRecord)

// Returns the following byte-encoded JSON string:
// {"one":1,"three":3,"two":2}

Encode a dynamic array of different basic types as JSON

Build a dynamic array where each element is a different basic type. This might be necessary if you’re send JSON data to an API that expects an array of values where each value is a different type. Values in a Flux array must be the same type, so you must build a dynamic array of dynamic types:

  1. Import the experimental/dynamic package.
  2. Use dynamic.dynamic()
    to convert the array to a dynamic type.
  3. Use dynamic.dynamic() to convert all values in the array to dynamic types.
  4. Use dynamic.jsonEncode() to convert the dynamic array into a byte-encoded JSON string.
import "experimental/dynamic"

arr =
    dynamic.dynamic(
        v: [
            dynamic.dynamic(v: "three"),
            dynamic.dynamic(v: 2),
            dynamic.dynamic(v: true)
        ],
    )

dynamic.jsonEncode(v: arr)

// Returns the following byte-encoded JSON string:
// ["three", 2, true]

Was this page helpful?

Thank you for your feedback!


Linux Package Signing Key Rotation

All signed InfluxData Linux packages have been resigned with an updated key. If using Linux, you may need to update your package configuration to continue to download and verify InfluxData software packages.

For more information, see the Linux Package Signing Key Rotation blog post.

InfluxDB Cloud backed by InfluxDB IOx

All InfluxDB Cloud organizations created on or after January 31, 2023 are backed by the new InfluxDB IOx storage engine. Check the right column of your InfluxDB Cloud organization homepage to see which InfluxDB storage engine you’re using.

If powered by IOx, this is the correct documentation.

If powered by TSM, see the TSM-based InfluxDB Cloud documentation.

InfluxDB Cloud backed by InfluxDB TSM

All InfluxDB Cloud organizations created on or after January 31, 2023 are backed by the new InfluxDB IOx storage engine which enables nearly unlimited series cardinality and SQL query support. Check the right column of your InfluxDB Cloud organization homepage to see which InfluxDB storage engine you’re using.

If powered by TSM, this is the correct documentation.

If powered by IOx, see the IOx-based InfluxDB Cloud documentation.

State of the InfluxDB Cloud (IOx) documentation

The new documentation for InfluxDB Cloud backed by InfluxDB IOx is a work in progress. We are adding new information and content almost daily. Thank you for your patience!

If there is specific information you’re looking for, please submit a documentation issue.