Error bulk importing Device Types on Import page #3515

Closed
opened 2025-12-29 18:29:36 +01:00 by adam · 6 comments
Owner

Originally created by @pth0rn on GitHub (Mar 27, 2020).

Originally assigned to: @jeremystretch on GitHub.

Environment

  • Python version: 3.7.7
  • NetBox version: 2.7.10

Steps to Reproduce

  1. Add several Device Types
  2. Export them to a YAML file
  3. Remove the devicetypes in netbox and try to re-import with YAML data

Expected Behavior

Import list of device types from YAML

Observed Behavior

Page throws error, seems that it does not like give it more than one object? It only works if you paste in 1 object without the --- separator.

Error:

<class 'yaml.composer.ComposerError'>

expected a single document in the stream
  in "<unicode string>", line 1, column 1:
    manufacturer: Ascom
    ^
but found another document
  in "<unicode string>", line 9, column 1:
    ---
    ^

I don't see any indications that the import feature only supports 1 object at a time. I believe in old versions you could bulk import via CSV. Isn't bulk import the reason for the import feature? So I'm assuming this is a bug.

Originally created by @pth0rn on GitHub (Mar 27, 2020). Originally assigned to: @jeremystretch on GitHub. <!-- NOTE: IF YOUR ISSUE DOES NOT FOLLOW THIS TEMPLATE, IT WILL BE CLOSED. This form is only for reproducible bugs. If you need assistance with NetBox installation, or if you have a general question, DO NOT open an issue. Instead, post to our mailing list: https://groups.google.com/forum/#!forum/netbox-discuss Please describe the environment in which you are running NetBox. Be sure that you are running an unmodified instance of the latest stable release before submitting a bug report. --> ### Environment * Python version: 3.7.7 * NetBox version: 2.7.10 <!-- Describe in detail the exact steps that someone else can take to reproduce this bug using the current stable release of NetBox (or the current beta release where applicable). Begin with the creation of any necessary database objects and call out every operation being performed explicitly. If reporting a bug in the REST API, be sure to reconstruct the raw HTTP request(s) being made: Don't rely on a wrapper like pynetbox. --> ### Steps to Reproduce 1. Add several Device Types 2. Export them to a YAML file 3. Remove the devicetypes in netbox and try to re-import with YAML data <!-- What did you expect to happen? --> ### Expected Behavior Import list of device types from YAML <!-- What happened instead? --> ### Observed Behavior Page throws error, seems that it does not like give it more than one object? It only works if you paste in 1 object without the --- separator. Error: ``` <class 'yaml.composer.ComposerError'> expected a single document in the stream in "<unicode string>", line 1, column 1: manufacturer: Ascom ^ but found another document in "<unicode string>", line 9, column 1: --- ^ ``` I don't see any indications that the import feature only supports 1 object at a time. I believe in old versions you could bulk import via CSV. Isn't bulk import the reason for the import feature? So I'm assuming this is a bug.
adam added the type: bugstatus: accepted labels 2025-12-29 18:29:36 +01:00
adam closed this issue 2025-12-29 18:29:36 +01:00
Author
Owner

@jeremystretch commented on GitHub (Mar 27, 2020):

Python version: 3

Please specify your exact Python version.

@jeremystretch commented on GitHub (Mar 27, 2020): > Python version: 3 Please specify your exact Python version.
Author
Owner

@pth0rn commented on GitHub (Mar 27, 2020):

Python version: 3
Please specify your exact Python version.

Thanks, done

@pth0rn commented on GitHub (Mar 27, 2020): > > Python version: 3 > > Please specify your exact Python version. Thanks, done
Author
Owner

@mtbutler07 commented on GitHub (Mar 27, 2020):

I can replicate this on 2.7.10 as well.
It appears as though the device type import feature is only expecting one YAML document.

When exporting device types from Netbox, all device types are combined into one yaml file and separated by '---'

@mtbutler07 commented on GitHub (Mar 27, 2020): I can replicate this on 2.7.10 as well. It appears as though the device type import feature is only expecting one YAML document. When exporting device types from Netbox, all device types are combined into one yaml file and separated by '---'
Author
Owner

@DanSheps commented on GitHub (Mar 27, 2020):

I believe this was a design decision undertaken when device templates were originally redone to allow importing of the components. This is a result of using yaml.load() vs yaml.load_all() and dealing with the additional logic of different documents being imported.

Personally, I don't see any reason to change the behavior, perhaps just clarify it, as you aren't generally going to be importing tens or hundreds of documents at one time. At most I would import a few documents as the need arises.

@DanSheps commented on GitHub (Mar 27, 2020): I believe this was a design decision undertaken when device templates were originally redone to allow importing of the components. This is a result of using yaml.load() vs yaml.load_all() and dealing with the additional logic of different documents being imported. Personally, I don't see any reason to change the behavior, perhaps just clarify it, as you aren't generally going to be importing tens or hundreds of documents at one time. At most I would import a few documents as the need arises.
Author
Owner

@pth0rn commented on GitHub (Mar 27, 2020):

I believe this was a design decision undertaken when device templates were originally redone to allow importing of the components. This is a result of using yaml.load() vs yaml.load_all() and dealing with the additional logic of different documents being imported.

Personally, I don't see any reason to change the behavior, perhaps just clarify it, as you aren't generally going to be importing tens or hundreds of documents at one time. At most I would import a few documents as the need arises.

Sadly I just spend 30 minutes importing hundreds individually via the import page because that was faster than finding another way to bulk import them lol via a script for example.

Personally it seems counter intuitive and inconvenient that other objects have bulk import option but device types do not. Especially when it can create an export but not import it back

Hope its addition is considered.

@pth0rn commented on GitHub (Mar 27, 2020): > I believe this was a design decision undertaken when device templates were originally redone to allow importing of the components. This is a result of using yaml.load() vs yaml.load_all() and dealing with the additional logic of different documents being imported. > > Personally, I don't see any reason to change the behavior, perhaps just clarify it, as you aren't generally going to be importing tens or hundreds of documents at one time. At most I would import a few documents as the need arises. Sadly I just spend 30 minutes importing hundreds individually via the import page because that was faster than finding another way to bulk import them lol via a script for example. Personally it seems counter intuitive and inconvenient that other objects have bulk import option but device types do not. Especially when it can create an export but not import it back Hope its addition is considered.
Author
Owner

@mtbutler07 commented on GitHub (Mar 27, 2020):

We went the route of scripting - used yaml.load.all() and pynetbox to create the device-types for a new Netbox install. I have to agree with @Vicvinegar0, having the ability to export all and not import all seems counter intuitive but I can understand the challenges involved with implementing that.

This a snippet of what we used, if that helps you with adding those back in the future.

with open("device-types.yaml", 'r') as f:
    data = list(yaml.safe_load_all(f))

    for item in data:
        item["manufacturer"] = nb.dcim.manufacturers.get(
            name=item["manufacturer"]).id
        nb.dcim.device_types.create(item)
        device_id = nb.dcim.device_types.get(model=item['model']).id

        if item.get("console-ports"):
            for console in item["console-ports"]:
                nb.dcim.console_port_templates.create(
                    [{"device_type": {"id": device_id}, "name": console["name"]}]
                )

        if item.get("power-ports"):
            for psu in item["power-ports"]:
                nb.dcim.power_port_templates.create(
                    [{"device_type": {"id": device_id}, "name": psu["name"]}]
                )

        if item.get("interfaces"):
            for interface in item["interfaces"]:
                nb.dcim.interface_templates.create(
                    [
                        {
                            "device_type": {"id": device_id},
                            "name": interface["name"],
                            "type": interface["type"],
                            "mgmt_only": interface["mgmt_only"]
                        }
                    ]
                )
@mtbutler07 commented on GitHub (Mar 27, 2020): We went the route of scripting - used `yaml.load.all()` and pynetbox to create the device-types for a new Netbox install. I have to agree with @Vicvinegar0, having the ability to export all and not import all seems counter intuitive but I can understand the challenges involved with implementing that. This a snippet of what we used, if that helps you with adding those back in the future. ```python with open("device-types.yaml", 'r') as f: data = list(yaml.safe_load_all(f)) for item in data: item["manufacturer"] = nb.dcim.manufacturers.get( name=item["manufacturer"]).id nb.dcim.device_types.create(item) device_id = nb.dcim.device_types.get(model=item['model']).id if item.get("console-ports"): for console in item["console-ports"]: nb.dcim.console_port_templates.create( [{"device_type": {"id": device_id}, "name": console["name"]}] ) if item.get("power-ports"): for psu in item["power-ports"]: nb.dcim.power_port_templates.create( [{"device_type": {"id": device_id}, "name": psu["name"]}] ) if item.get("interfaces"): for interface in item["interfaces"]: nb.dcim.interface_templates.create( [ { "device_type": {"id": device_id}, "name": interface["name"], "type": interface["type"], "mgmt_only": interface["mgmt_only"] } ] ) ```
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/netbox#3515