Update custom metadata
You need to send the entire custom metadata structure (all of its attributes) on each update.
Retrieve existing structure
To make sure you have the complete structure, it's easiest to start by retrieving the existing custom metadata structure.
Update custom metadata structure
Now that you have the existing structure, modify the object. You can add or remove as many properties as you want in a single update, but for simplicity the following describe how to add and remove a single property each.
Add property
To add a property:
- Java
- Python
- Kotlin
- Raw REST API
existing.toBuilder() // (6)
.attributeDef(AttributeDef.of(client, // (2)
"Extra", // (3)
AtlanCustomAttributePrimitiveType.STRING, // (4)
false)) // (5)
.build(); // (6)
CustomMetadataDef updated = existing.update(client); // (7)
- After retrieving the existing custom metadata structure, clone the structure into a mutable one using
toBuilder(). - You can append a new attribute to its list of attributes by chaining
.attributeDef(). Use theAttributeDef.of()factory method to define the attribute with the correct internal settings. Because this operation may need to retrieve information from Atlan, you must provide it anAtlanClientthrough which to connect to the tenant. - When using the factory method, you need to provide at least a name;
- ...a type;
- ...and whether there can be multiple values for this property (true) or only a single value (false) on a given asset.
- Then build the mutable structure.
- And finally call the
.update()method on the revised custom metadata structure to actually submit the changes to Atlan. Because this operation will persist the structure in Atlan, you must provide it anAtlanClientthrough which to connect to the tenant.
from pyatlan.model.typedef import AttributeDef
from pyatlan.model.enums import AtlanCustomAttributePrimitiveType
from pyatlan.client.atlan import AtlanClient
client = AtlanClient()
attrs = existing.attribute_defs # (1)
attrs.append(
AttributeDef.create( # (2)
client=client, # (3)
display_name="Extra", # (4)
attribute_type=AtlanCustomAttributePrimitiveType.STRING,
),
)
existing.attribute_defs = attrs # (5)
response = client.typedef.update(existing) # (6)
- Create a new list of attributes, starting with the list of existing attributes.
- Add a new attribute to this list of attributes. Use the
AttributeDef.create()factory method to define the attribute with the correct internal settings. - You must provide a client instance.
- When using the factory method, you need to provide at least a name and a type.
- Then set the attributes on the custom metadata structure to this revised list.
- And finally call the
.typedef.update()method sending the revised custom metadata structure to actually submit the changes to Atlan.
existing.toBuilder() // (6)
.attributeDef(AttributeDef.of(client, // (2)
"Extra", // (3)
AtlanCustomAttributePrimitiveType.STRING, // (4)
false)) // (5)
.build() // (6)
val updated = existing.update(client) // (7)
- After retrieving the existing custom metadata structure, clone the structure into a mutable one using
toBuilder(). - You can append a new attribute to its list of attributes by chaining
.attributeDef(). Use theAttributeDef.of()factory method to define the attribute with the correct internal settings. Because this operation may need to retrieve information from Atlan, you must provide it anAtlanClientthrough which to connect to the tenant. - When using the factory method, you need to provide at least a name;
- ...a type;
- ...and whether there can be multiple values for this property (true) or only a single value (false) on a given asset.
- Then build the mutable structure.
- And finally call the
.update()method on the revised custom metadata structure to actually submit the changes to Atlan. Because this operation will persist the structure in Atlan, you must provide it anAtlanClientthrough which to connect to the tenant.
{
"businessMetadataDefs": [ // (1)
},
{...},
{...},
{...},
{
"name": "Extra", // (4)
"displayName": "Extra", // (5)
"description": "",
"typeName": "string",
"includeInNotification": false,
"isIndexable": true,
"isOptional": true,
"isUnique": false,
"indexType": "DEFAULT",
"searchWeight": -1,
"cardinality": "SINGLE",
"valuesMinCount": 0,
"valuesMaxCount": 1,
"options": {
"applicableEntityTypes": "[\"Asset\"]",
"customApplicableEntityTypes": "[\"Database\",\"Schema\",\"Table\"]\n",
"maxStrLength": "100000000",
"isEnum": false,
"multiValueSelect": false,
"allowFiltering": true,
"allowSearch": true,
"primitiveType": "string",
"customType": "users"
}
}
],
"createdBy": "jsmith",
"updatedBy": "jsmith",
"createTime": 1648852296555,
"updateTime": 1649172284333,
"version": 2
}
]
}
- You need to specify the entire custom metadata structure, within the
businessMetadataDefsarray. - Include all the details of the custom metadata structure definition as you retrieved it.
- Include all the details of the custom metadata attribute definitions, as you retrieved them.
- Add the new attribute definition to the list of attribute definitions. Note that for the
nameduring this update you can use any string you want, as it will be replaced by a system-generated hashed-string during creation of the property. - However, make sure you use the human-readable name you want for the property for the
displayNameof the attribute definition. Also make sure you set all the remaining pieces of the attribute definition according to the nature of the attribute you want to define.
Change property
To change an existing property:
- Java
- Python
- Kotlin
- Raw REST API
List<AttributeDef> revised = new ArrayList<>(); // (1)
for (AttributeDef attr : existing.getAttributeDefs()) else {
revised.add(attr); // (4)
}
}
existing.toBuilder() // (5)
.clearAttributeDefs() // (6)
.attributeDefs(revised) // (7)
.build();
CustomMetadataDef updated = existing.update(client); // (8)
-
Create a new (mutable) empty list of attributes.
-
Iterate through the existing attributes in the custom metadata structure...
-
...When you get to the attribute you want to change, modify it as-needed.
Some properties must not be changed
Don't change the attribute's primitiveType, isEnum, enumType, customType, multiValueSelect, isArchived, archivedAt, or archivedBy properties. These should only be set at creation or through archival methods.
:::
4. And add all attributes (existing and the modified one) into the list of revised attributes.
5. You must then clone the custom metadata structure into a mutable structure, using toBuilder().
6. You then need to clear the existing attribute definitions (otherwise the next step will only append the same definitions again).
7. Then you can set the attributes on the custom metadata structure to this revised list, and build the structure.
8. And finally call the .update() method on the revised custom metadata structure to actually submit the changes to Atlan. Because this operation will persist the structure in Atlan, you must provide it an AtlanClient through which to connect to the tenant.
from pyatlan.model.typedef import AttributeDef
from pyatlan.model.enums import AtlanCustomAttributePrimitiveType
revised = [] # (1)
for attr in existing.attribute_defs: # (2)
if attr.display_name == "Extra":
attr.display_name = "Something else" # (3)
revised.append(attr) # (4)
existing.attribute_defs = revised # (5)
from pyatlan.client.atlan import AtlanClient
client = AtlanClient()
response = client.typedef.update(existing) # (6)
- Create a new empty list of attributes.
- Iterate through the existing attributes in the custom metadata structure...
- ...When you get to the attribute you want to change, you can change its
display_name, but not much else. (You shouldn't change its type, hashed-string name, etc.) - And add all attributes (existing and the modified one) into the list of revised attributes.
- Then set the attributes on the custom metadata structure to this revised list.
- And finally call the
typedef.update()method sending the revised custom metadata structure to actually submit the changes to Atlan.
val revised = mutableListOf<AttributeDef>() // (1)
for (attr in existing.attributeDefs) else {
revised.add(attr) // (4)
}
}
existing.toBuilder() // (5)
.clearAttributeDefs() // (6)
.attributeDefs(revised) // (7)
.build()
val updated = existing.update(client) // (8)
-
Create a new (mutable) empty list of attributes.
-
Iterate through the existing attributes in the custom metadata structure...
-
...When you get to the attribute you want to change, modify it as-needed.
Some properties must not be changed
Don't change the attribute's primitiveType, isEnum, enumType, customType, multiValueSelect, isArchived, archivedAt, or archivedBy properties. These should only be set at creation or through archival methods.
:::
4. And add all attributes (existing and the modified one) into the list of revised attributes.
5. You must then clone the custom metadata structure into a mutable structure, using toBuilder().
6. You then need to clear the existing attribute definitions (otherwise the next step will only append the same definitions again).
7. Then you can set the attributes on the custom metadata structure to this revised list, and build the structure.
8. And finally call the .update() method on the revised custom metadata structure to actually submit the changes to Atlan. Because this operation will persist the structure in Atlan, you must provide it an AtlanClient through which to connect to the tenant.
{
"businessMetadataDefs": [ // (1)
},
{...},
{...},
{...},
{
"name": "okm7BDXjTQx4iYPT5u7ilu", // (4)
"displayName": "Something else", // (5)
"description": "",
"typeName": "string",
"includeInNotification": false,
"isIndexable": true,
"isOptional": true,
"isUnique": false,
"indexType": "DEFAULT",
"searchWeight": -1,
"cardinality": "SINGLE",
"valuesMinCount": 0,
"valuesMaxCount": 1,
"options": {
"applicableEntityTypes": "[\"Asset\"]",
"customApplicableEntityTypes": "[\"Database\",\"Schema\",\"Table\"]\n",
"maxStrLength": "100000000",
"isEnum": false,
"multiValueSelect": false,
"allowFiltering": true,
"allowSearch": true,
"primitiveType": "string",
"customType": "users"
}
}
],
"createdBy": "jsmith",
"updatedBy": "jsmith",
"createTime": 1648852296555,
"updateTime": 1649172284333,
"version": 2
}
]
}
- You need to specify the entire custom metadata structure, within the
businessMetadataDefsarray. - Include all the details of the custom metadata structure definition as you retrieved it.
- Include all the details of the custom metadata attribute definitions, as you retrieved them.
- For the attribute you want to modify, include its hashed-string name as with all the other attribute definitions.
- However, for the
displayNameof the attribute you want to modify, change it to the new human-readable name you want to use.
Remove property
To remove a property:
- Java
- Python
- Kotlin
- Raw REST API
List<AttributeDef> revised = new ArrayList<>(); // (1)
for (AttributeDef attr : existing.getAttributeDefs()) else {
revised.add(attr); // (4)
}
}
existing.toBuilder() // (5)
.clearAttributeDefs() // (6)
.attributeDefs(revised) // (7)
.build();
CustomMetadataDef updated = existing.update(client); // (8)
- Create a new (mutable) empty list of attributes.
- Iterate through the existing attributes in the custom metadata structure...
- ...When you get to the attribute you want to remove, call the
.archive()method against it passing the name of the user deleting the attribute. - And add all attributes (existing and the removed one) into the list of revised attributes.
- You must then clone the custom metadata structure into a mutable structure, using
toBuilder(). - You then need to clear the existing attribute definitions (otherwise the next step will only append the same definitions again).
- Then you can set the attributes on the custom metadata structure to this revised list, and build the structure.
- And finally call the
.update()method on the revised custom metadata structure to actually submit the changes to Atlan. Because this operation will persist the structure in Atlan, you must provide it anAtlanClientthrough which to connect to the tenant.
from pyatlan.model.typedef import AttributeDef
from pyatlan.model.enums import AtlanCustomAttributePrimitiveType
revised = [] # (1)
for attr in existing.attribute_defs: # (2)
if attr.display_name == "Extra":
attr.archive(by="jsmith") # (3)
revised.append(attr) # (4)
existing.attribute_defs = revised # (5)
from pyatlan.client.atlan import AtlanClient
client = AtlanClient()
response = client.typedef.update(existing) # (6)
- Create a new empty list of attributes.
- Iterate through the existing attributes in the custom metadata structure...
- ...When you get to the attribute you want to remove, call the
.archive()method against it passing the name of the user deleting the attribute. - And add all attributes (existing and the archived one) into the list of revised attributes.
- Then set the attributes on the custom metadata structure to this revised list.
- And finally call the
.update()method on the revised custom metadata structure to actually submit the changes to Atlan.
val revised = mutableListOf<AttributeDef>() // (1)
for (attr in existing.attributeDefs) else {
revised.add(attr) // (4)
}
}
existing.toBuilder() // (5)
.clearAttributeDefs() // (6)
.attributeDefs(revised) // (7)
.build()
val updated = existing.update(client) // (8)
- Create a new (mutable) empty list of attributes.
- Iterate through the existing attributes in the custom metadata structure...
- ...When you get to the attribute you want to remove, call the
.archive()method against it passing the name of the user deleting the attribute. - And add all attributes (existing and the removed one) into the list of revised attributes.
- You must then clone the custom metadata structure into a mutable structure, using
toBuilder(). - You then need to clear the existing attribute definitions (otherwise the next step will only append the same definitions again).
- Then you can set the attributes on the custom metadata structure to this revised list, and build the structure.
- And finally call the
.update()method on the revised custom metadata structure to actually submit the changes to Atlan. Because this operation will persist the structure in Atlan, you must provide it anAtlanClientthrough which to connect to the tenant.
{
"businessMetadataDefs": [ // (1)
},
{...},
{...},
{...},
{
"name": "okm7BDXjTQx4iYPT5u7ilu", // (4)
"displayName": "Extra-archived-1649172285912", // (5)
"description": "",
"typeName": "string",
"includeInNotification": false,
"isIndexable": true,
"isOptional": true,
"isUnique": false,
"indexType": "DEFAULT",
"searchWeight": -1,
"cardinality": "SINGLE",
"valuesMinCount": 0,
"valuesMaxCount": 1,
"options": {
"applicableEntityTypes": "[\"Asset\"]",
"customApplicableEntityTypes": "[\"Database\",\"Schema\",\"Table\"]\n",
"maxStrLength": "100000000",
"isEnum": false,
"multiValueSelect": false,
"allowFiltering": true,
"allowSearch": true,
"primitiveType": "string",
"customType": "users",
"isArchived": true, // (6)
"archivedBy": "jsmith", // (7)
"archivedAt": 1649172285912 // (8)
}
}
],
"createdBy": "jsmith",
"updatedBy": "jsmith",
"createTime": 1648852296555,
"updateTime": 1649172284333,
"version": 2
}
]
}
- You need to specify the entire custom metadata structure, within the
businessMetadataDefsarray. - Include all the details of the custom metadata structure definition as you retrieved it.
- Include all the details of the custom metadata attribute definitions, as you retrieved them.
- For the attribute you want to remove, include its hashed-string name as with all the other attribute definitions.
- However, for the
displayNameof the attribute you want to remove, append-archived-and a millisecond epoch for the current system time. - Within the
optionsfor the attribute definition, setisArchivedtotrue. - Within the
optionsfor the attribute definition, setarchivedByto the name of the user who is deleting the attribute. - Within the
optionsfor the attribute definition, setarchivedAtto the millisecond epoch appended to thedisplayName.
Note that removing a property only archives (soft-deletes) it. When retrieving the custom metadata structure again, you will still see the deleted attribute definition in the structure, but its attributeDefs.options.isArchived property will be set to true and its displayName will have been changed to include the time at which it was archived.