Change custom metadata on assets
Remember that you must first create the custom metadata structures before you will be able to set or change any values for custom metadata on an asset.
Value representation
To update custom metadata values on an asset, you need to use the correct representation:
| Property type | Value representation | Example |
|---|---|---|
| Text | String | "a value" |
| Integer | Number: without decimals | 42 |
| Decimal | Number: with decimals | 42.0 |
| Boolean | Boolean: either true or false | true |
| Date | Number: milliseconds since epoch (January 1, 1970), to a specific day | 1681171200000 |
| Options | String: exact value from the options list | "success" |
| Users | String: username of the user | "jsmith" |
| Groups | String: unique name of the group, which appears under the name of the group in the UI list of groups | "finance" |
| URL | String: starting with http[s]:// | https://www.google.com |
| SQL | String | "SELECT *\nFROM somewhere;" |
Custom attributes in Atlan can be configured to allow multiple values. For these, you must wrap all values in a multi-valued collection, even if there is only a single value you are setting. Each value in that collection needs to follow the appropriate representation as indicated in the table above.
For example, if you want to set just a single group in a field that allows multiple values:
dbt
models:
- name: TOP_BEVERAGE_USERS
meta:
atlan:
businessAttributes:
MNJ8mpLsIOaP4OQnLNhRta:
F8XI9GzcBpdBdfi4cLiPEz:
- "finance" # (1)
-
You must provide the values as a list in YAML: each value on a new line, indented below the attribute, and prefixed with
-.Java
CustomMetadataAttributes cmRACI = CustomMetadataAttributes.builder()
.attribute("Consulted", List.of("finance")) // (1)
.build();
-
You must provide the values as a collection (List, Set, etc).
Python
from pyatlan.model.custom_metadata import CustomMetadataDict
cm_RACI = CustomMetadataDict(client=client, name="RACI") # (1)
cm_RACI["Consulted"] = ["finance"] # (2)
-
Provide the client instance and name of the custom metadata set.
Name will be validated
The name will be validated at runtime to make sure that a custom metadata set with the given name exists. ::: 2. For any property that can be multi-valued, we need to send a list of values.
The metadata property name will be validated at runtime to make sure that a property with the given name exists in the custom metadata set.
Kotlin
val cmRACI = CustomMetadataAttributes.builder()
.attribute("Consulted", listOf("finance")) // (1)
.build()
-
You must provide the values as a collection (List, Set, etc).
Raw REST API
{
"MNJ8mpLsIOaP4OQnLNhRta": {
"F8XI9GzcBpdBdfi4cLiPEz": [ // (1)
"finance"
]
}
}
- You must provide the values in a JSON-style array.
Add to existing assets
Update only some custom metadata attributes
To update only some custom metadata attributes (leaving all others unchanged):
- dbt
- Java
- Python
- Kotlin
- Raw REST API
This is currently not possible via dbt, custom metadata is replaced rather than selectively updated.
CustomMetadataAttributes cmRACI = CustomMetadataAttributes.builder() // (1)
.attribute("Responsible", "jsmith") // (2)
.attribute("Consulted", List.of("finance", "risk")) // (3)
.build();
Table.updateCustomMetadataAttributes( // (4)
client, // (5)
"b4113341-251b-4adc-81fb-2420501c30e6", // (6)
"RACI", // (7)
cmRACI); // (8)
-
Create a custom metadata attributes object that will contain only the attributes and values for custom metadata that you want to update on the asset. All other custom metadata attributes (those not specified in this object) will remain unchanged on the asset.
-
For each attribute, use the
attribute()method and pass:- the name of the attribute within that set
- the value for that attribute
The value can be any object valid for the attribute: a string, a boolean, or a number. (Note that dates are sent as
long(epoch) numbers.) -
For any attribute that can be multi-valued, we can send a list of values.
-
Use the
updateCustomMetadataAttributes()method to update only theResponsibleandConsultedattributes in theRACIcustom metadata on the existing asset. Any other custom metadata attributes inRACIand all other custom metadata will be left unchanged. -
Because this operation will directly change the asset in Atlan, you must provide it an
AtlanClientthrough which to connect to the tenant. -
Note that for this operation you must know the GUID of the asset you want to apply the custom metadata to. Also, the operation returns no result: if there is an error it will throw an exception, but the result of the operation must be determined by retrieving the asset through a separate API call, if you want to confirm it.
-
Provide the name for the custom metadata you want to update.
-
Provide the custom metadata attributes object with the attributes and values you want to update for that custom metadata.
from pyatlan.client.atlan import AtlanClient
from pyatlan.model.assets import Table
client = AtlanClient()
table = Table.updater( # (1)
qualified_name="default/snowflake/1657037873/SAMPLE_DB/FOOD_BEV",
name="default/snowflake/1657037873/SAMPLE_DB/FOOD_BEV",
)
- Use the
updater()method to create an asset suitable for modifiaction that is, with all the requisite attributes.
cm_raci = table.get_custom_metadata(client=client, name="RACI") # (1)
cm_raci["Responsible"] = "jsmith" # (2)
cm_raci["Consulted"] = ["finance", "risk"] # (3)
-
Get the custom metadata set from the table via the
get_custom_metadatamethod by specifying the client and name of the custom metadata set.Name will be validated
The name will be validated at runtime to make sure that a custom metadata set with the given name exists. ::: 2. For each property of the metadata set you wish to update specify the name of the property.
The metadata property name will be validated at runtime to make sure that a property with the given name exists in the custom metadata set.
- For any attribute that can be multi-valued, we need to send a list of values.
cm_raci = CustomMetadataDict(client=client, name="RACI") # (1)
cm_raci["Responsible"] = "jsmith" # (2)
cm_raci["Consulted"] = ["finance", "risk"] # (3)
table.set_custom_metadata(client=client, custom_metadata=cm_raci) # (4)
-
Create an empty custom metadata set by specifying the client instance and name of an existing custom metadata set.
Name will be validated
The name will be validated at runtime to make sure that a custom metadata set with the given name exists. ::: 2. For each property of the metadata set you wish to update specify the name of the property.
The metadata property name will be validated at runtime to make sure that a property with the given name exists in the custom metadata set.
- For any attribute that can be multi-valued, we need to send a list of values.
- Use the
set_custom_metadatamethod to set the custom metadata set on the table.
response = client.asset.save_merging_cm( # (1)
table
)
assert (tables := response.assets_updated(asset_type=Table)) # (2)
- Use the
save_merging_cm()method to update the model object on the server. - Assert that a
Tableasset has been updated.
val cmRACI = CustomMetadataAttributes.builder() // (1)
.attribute("Responsible", "jsmith") // (2)
.attribute("Consulted", listOf("finance", "risk")) // (3)
.build()
Table.updateCustomMetadataAttributes( // (4)
client, // (5)
"b4113341-251b-4adc-81fb-2420501c30e6", // (6)
"RACI", // (7)
cmRACI) // (8)
-
Create a custom metadata attributes object that will contain only the attributes and values for custom metadata that you want to update on the asset. All other custom metadata attributes (those not specified in this object) will remain unchanged on the asset.
-
For each attribute, use the
attribute()method and pass:- the name of the attribute within that set
- the value for that attribute
The value can be any object valid for the attribute: a string, a boolean, or a number. (Note that dates are sent as
long(epoch) numbers.) -
For any attribute that can be multi-valued, we can send a list of values.
-
Use the
updateCustomMetadataAttributes()method to update only theResponsibleandConsultedattributes in theRACIcustom metadata on the existing asset. Any other custom metadata attributes inRACIand all other custom metadata will be left unchanged. -
Because this operation will directly change the asset in Atlan, you must provide it an
AtlanClientthrough which to connect to the tenant. -
Note that for this operation you must know the GUID of the asset you want to apply the custom metadata to. Also, the operation returns no result: if there is an error it will throw an exception, but the result of the operation must be determined by retrieving the asset through a separate API call, if you want to confirm it.
-
Provide the name for the custom metadata you want to update.
-
Provide the custom metadata attributes object with the attributes and values you want to update for that custom metadata.
{ // (1)
"MNJ8mpLsIOaP4OQnLNhRta": { // (2)
"fWMB77RSjRGNYoFeD4FcGi": "jsmith", // (3)
"F8XI9GzcBpdBdfi4cLiPEz": [ // (4)
"finance",
"risk"
]
}
}
- You must pass the GUID of the asset to change for this operation. There is no alternative that works with the qualifiedName.
- Each custom metadata set you want to add or update must be given using its hashed-string representation.
- Each custom metadata attribute you want to update must be given using its hashed-string representation.
- For multivalued custom metadata attributes, specify the value as an array.
Replace some custom metadata on asset
You can also add/replace an entire set of custom metadata to existing assets. If you do this individually, you can selectively update individual sets of custom metadata (leaving any others unchanged):
- dbt
- Java
- Python
- Kotlin
- Raw REST API
models:
- name: TOP_BEVERAGE_USERS # (1)
meta:
atlan:
businessAttributes: # (2)
MNJ8mpLsIOaP4OQnLNhRta: # (3)
fWMB77RSjRGNYoFeD4FcGi: jsmith # (4)
F8XI9GzcBpdBdfi4cLiPEz: [ "finance", "risk" ] # (5)
businessAttributeNames: # (6)
RACI:
Informed:
- "marketing"
- You must of course give the name of the object.
- The custom metadata must be nested within the
meta.atlan.businessAttributesstructure. - Each custom metadata set you want to add or update must be given using its hashed-string representation.
- Each custom metadata attribute you want to update must be given using its hashed-string representation.
- For multivalued custom metadata attributes, specify the value as an array.
- You can use
displayNamesinstead of hashed-string representations by nesting custom metadata withinmeta.atlan.businessAttributeNamesstructure.
CustomMetadataAttributes cmRACI = CustomMetadataAttributes.builder() // (1)
.attribute("Responsible", "jsmith") // (2)
.attribute("Consulted", List.of("finance", "risk")) // (3)
.build();
Table.replaceCustomMetadata( // (4)
client, // (5)
"b4113341-251b-4adc-81fb-2420501c30e6", // (6)
"RACI", // (7)
cmRACI); // (8)
-
Create a custom metadata attributes object that will contain the attributes and values for custom metadata you want to add to the asset.
-
For each attribute, use the
attribute()method and pass:- the name of the attribute within that set
- the value for that attribute
The value can be any object valid for the attribute: a string, a boolean, or a number. (Note that dates are sent as
long(epoch) numbers.) -
For any attribute that can be multi-valued, we can send a list of values.
-
Use the
replaceCustomMetadata()method to replace only this namedRACIcustom metadata on the existing asset. Any other custom metadata will be left unchanged. Note that any attributes inRACIthat are not included in the custom metadata attributes object we send will be removed from the custom metadata on that asset. (In our examples, this means any existing values in theAccountableandInformedattributes ofRACIon this asset would be removed.) -
Because this operation will directly change the asset in Atlan, you must provide it an
AtlanClientthrough which to connect to the tenant. -
Note that for this operation you must know the GUID of the asset you want to apply the custom metadata to. Also, the operation returns no result: if there is an error it will throw an exception, but the result of the operation must be determined by retrieving the asset through a separate API call, if you want to confirm it.
-
Provide the name for the custom metadata you want to add/replace.
-
Provide the custom metadata attributes object with the attributes and values you want to be the complete set for that custom metadata.
from pyatlan.client.atlan import AtlanClient
from pyatlan.model.custom_metadata import CustomMetadataDict
client = AtlanClient()
raci = CustomMetadataDict(client=client, name="RACI") # (1)
raci["Responsible"] = ["jsmith"] # (2)
raci["Consulted"] = ["finance", "risk"] # (3)
client.asset.replace_custom_metadata( # (4)
guid="b4113341-251b-4adc-81fb-2420501c30e6", #(5)
custom_metadata=raci # (6)
)
-
Create an empty custom metadata set by specifying the client instance and name of an existing custom metadata set.
Name will be validated
The name will be validated at runtime to make sure that a custom metadata set with the given name exists. ::: 2. For each property of the metadata set you wish to update specify the name of the property.
The metadata property name will be validated at runtime to make sure that a property with the given name exists in the custom metadata set.
- For any property that can be multi-valued, we need to send a list of values.
- Use the
asset.replace_custom_metadata()method to replace only this namedRACIcustom metadata on the existing asset. Any other custom metadata will be left unchanged. Note that any properties inRACIthat are not included in the custom metadata object we send will be removed from the custom metadata on that asset. (In our examples, this means any existing values in theAccountableandInformedproperties ofRACIon this asset would be removed.) - Note that for this operation you must know the GUID of the asset you want to apply the custom metadata to. Also, the operation returns no result: if there is an error it will throw an exception, but the result of the operation must be determined by retrieving the asset through a separate API call, if you want to confirm it.
- Provide the custom metadata set object with the properties and values you want to be the complete set for that custom metadata.
val cmRACI = CustomMetadataAttributes.builder() // (1)
.attribute("Responsible", "jsmith") // (2)
.attribute("Consulted", listOf("finance", "risk")) // (3)
.build()
Table.replaceCustomMetadata( // (4)
client, // (5)
"b4113341-251b-4adc-81fb-2420501c30e6", // (6)
"RACI", // (7)
cmRACI) // (8)
-
Create a custom metadata attributes object that will contain the attributes and values for custom metadata you want to add to the asset.
-
For each attribute, use the
attribute()method and pass:- the name of the attribute within that set
- the value for that attribute
The value can be any object valid for the attribute: a string, a boolean, or a number. (Note that dates are sent as
long(epoch) numbers.) -
For any attribute that can be multi-valued, we can send a list of values.
-
Use the
replaceCustomMetadata()method to replace only this namedRACIcustom metadata on the existing asset. Any other custom metadata will be left unchanged. Note that any attributes inRACIthat are not included in the custom metadata attributes object we send will be removed from the custom metadata on that asset. (In our examples, this means any existing values in theAccountableandInformedattributes ofRACIon this asset would be removed.) -
Because this operation will directly change the asset in Atlan, you must provide it an
AtlanClientthrough which to connect to the tenant. -
Note that for this operation you must know the GUID of the asset you want to apply the custom metadata to. Also, the operation returns no result: if there is an error it will throw an exception, but the result of the operation must be determined by retrieving the asset through a separate API call, if you want to confirm it.
-
Provide the name for the custom metadata you want to add/replace.
-
Provide the custom metadata attributes object with the attributes and values you want to be the complete set for that custom metadata.
{ // (1)
"MNJ8mpLsIOaP4OQnLNhRta": { // (2)
"fWMB77RSjRGNYoFeD4FcGi": "jsmith", // (3)
"F8XI9GzcBpdBdfi4cLiPEz": [ // (4)
"finance",
"risk"
]
}
}
- You must pass the GUID of the asset to change for this operation. There is no alternative that works with the qualifiedName. Note that you also need the hashed-string representation of the custom metadata set in the URL itself.
- Each custom metadata set you want to replace must be given using its hashed-string representation.
- Each custom metadata attribute you want to include in the replacement must be given using its hashed-string representation.
- For multivalued custom metadata attributes, specify the value as an array.
You can iteratively migrate from using businessAttributes to businessAttributeNames with dbt. But remember to not define the same attribute under both.
Replace all custom metadata on asset
Remember that Atlan matches the provided qualifiedName to determine whether to update or create the asset.
You can also replace all the custom metadata on one or many existing assets at the same time.
This approach will replace all existing custom metadata (across all attributes) on the asset. If you have only a few custom metadata attributes defined in the update, this will remove any other custom metadata attributes that are already set on the asset within Atlan.
- dbt
- Java
- Python
- Kotlin
- Raw REST API
models:
- name: TOP_BEVERAGE_USERS # (1)
meta:
atlan:
businessAttributes: # (2)
MNJ8mpLsIOaP4OQnLNhRta: # (3)
fWMB77RSjRGNYoFeD4FcGi: jsmith # (4)
F8XI9GzcBpdBdfi4cLiPEz: [ "finance", "risk" ] # (5)
foMg7yOwUajucuya0JEF4J: # (6)
uTmK5o0J8jHTH3KWFXXeZi: example # (7)
- You must of course give the name of the object.
- The custom metadata must be nested within the
meta.atlan.businessAttributesstructure. - Each custom metadata set you want to add or update must be given using its hashed-string representation.
- Each custom metadata attribute you want to update must be given using its hashed-string representation.
- For multivalued custom metadata attributes, specify the value as an array.
- Additional custom metadata sets would be listed as additional sub-objects of the
businessAttributesobject. (Still using a hashed-string representation.) - ...and custom metadata attributes within those sets would be listed as sub-objects of the custom metadata set object. (Still using a hashed-string representation.)
CustomMetadataAttributes cmRACI = CustomMetadataAttributes.builder() // (1)
.attribute("Responsible", "jsmith")
.attribute("Consulted", List.of("finance", "risk"))
.build();
CustomMetadataAttributes cmOther = CustomMetadataAttributes.builder() // (2)
.attribute("Another", "example")
.build();
Table table = Table
.updater("default/snowflake/1657037873/SAMPLE_DB/FOOD_BEV/TOP_BEVERAGE_USERS", // (3)
"TOP_BEVERAGE_USERS")
.customMetadata("RACI", cmRACI) // (4)
.customMetadata("Other", cmOther) // (5)
.build(); // (6)
AssetMutationResponse response = table.saveReplacingCM(client, false); // (7)
assert response.getUpdatedAssets().size() == 1 // (8)
- Create one or more custom metadata attributes objects that will contain all the custom metadata you want the asset to have.
- You can create as many custom metadata attributes objects as you have named sets of custom metadata.
- Use the
updater()method to initialize the object with all necessary attributes for updating it. - Directly chain the custom metadata attributes onto the
updater()method's result. Note that the first parameter needs to be the name of the custom metadata that contains these attributes. - Continue chaining custom metadata attributes onto each other, if you have multiple sets of custom metadata you want to include in the replacement.
- Call the
build()method to build the enriched object. - Call the
saveReplacingCM()method to replace the custom metadata for the asset in Atlan. (If you usesave()then no custom metadata updates will be made; while usingsaveMergingCM()will only update any new or changed values.) Because this operation will persist the asset in Atlan, you must provide it anAtlanClientthrough which to connect to the tenant. - The response will include all assets that were updated.
from pyatlan.client.atlan import AtlanClient
from pyatlan.model.assets import Table
from pyatlan.model.custom_metadata import CustomMetadataDict
client = AtlanClient()
table = Table.updater( # (1)
qualified_name="default/snowflake/1657037873/SAMPLE_DB/FOOD_BEV/TOP_BEVERAGE_USERS",
name="TOP_BEVERAGE_USERS",
)
cm_raci = CustomMetadataDict( # (2)
client=client,
name="RACI", # (3)
)
cm_raci["Responsible"] = "jsmith" # (4)
cm_raci["Consulted"] = ["finance", "risk"] # (5)
cm_other = CustomMetadataDict(
client=client,
name="Other",
)
cm_other["Another"] = "example"
table.set_custom_metadata(client=client, custom_metadata=cm_raci) # (6)
table.set_custom_metadata(client=client, custom_metadata=cm_other) # (7)
response = client.asset.save_replacing_cm( # (8)
table
)
assert (tables := response.assets_updated(asset_type=Table)) # (9)
-
Use the
updater()method to create an asset suitable for modifiaction that is, with all the required attributes. -
Create a new instance of CustomMetadataDict.
-
Provide the name of an existing custom metadata set.
Name will be validated
The name will be validated at runtime to make sure that a custom metadata set with the given name exists. ::: 4. For each property that you want to set, specify the property name.
The metadata property name will be validated at runtime to make sure that a property with the given name exists in the custom metadata set.
- For any property that can be multi-valued, we need to send a list of values.
- Use the
set_custom_metadata()method to add the custom metadata to the model object. - You must call
set_custom_metadata()for each set of custom metadata. - Use the
save_replacing_cm()method to update the model object on the server. - Assert that a
Tableasset has been updated.
val cmRACI = CustomMetadataAttributes.builder() // (1)
.attribute("Responsible", "jsmith")
.attribute("Consulted", listOf("finance", "risk"))
.build()
val cmOther = CustomMetadataAttributes.builder() // (2)
.attribute("Another", "example")
.build()
val table = Table
.updater("default/snowflake/1657037873/SAMPLE_DB/FOOD_BEV/TOP_BEVERAGE_USERS", // (3)
"TOP_BEVERAGE_USERS")
.customMetadata("RACI", cmRACI) // (4)
.customMetadata("Other", cmOther) // (5)
.build() // (6)
val response = table.saveReplacingCM(client, false) // (7)
assert(response.updatedAssets.size == 1) // (8)
- Create one or more custom metadata attributes objects that will contain all the custom metadata you want the asset to have.
- You can create as many custom metadata attributes objects as you have named sets of custom metadata.
- Use the
updater()method to initialize the object with all necessary attributes for updating it. - Directly chain the custom metadata attributes onto the
updater()method's result. Note that the first parameter needs to be the name of the custom metadata that contains these attributes. - Continue chaining custom metadata attributes onto each other, if you have multiple sets of custom metadata you want to include in the replacement.
- Call the
build()method to build the enriched object. - Call the
saveReplacingCM()method to replace the custom metadata for the asset in Atlan. (If you usesave()then no custom metadata updates will be made; while usingsaveMergingCM()will only update any new or changed values.) Because this operation will persist the asset in Atlan, you must provide it anAtlanClientthrough which to connect to the tenant. - The response will include all assets that were updated.
{ // (1)
"entities": [ // (2),
"businessAttributes": { // (6)
"MNJ8mpLsIOaP4OQnLNhRta": { // (7)
"fWMB77RSjRGNYoFeD4FcGi": "jsmith", // (8)
"F8XI9GzcBpdBdfi4cLiPEz": [
"finance",
"risk"
]
},
"foMg7yOwUajucuya0JEF4J": { // (9)
"uTmK5o0J8jHTH3KWFXXeZi": "example" // (10)
}
}
}
]
}
- Note that the query parameters
replaceBusinessAttributesandoverwriteBusinessAttributesmust both equaltruein the request. This is what causes the replacement behavior. - All assets must be wrapped in an
entitiesarray. - You must provide the exact type name for the asset (case-sensitive).
- You must provide the exact
qualifiedNameof the asset (case-sensitive). - You must provide the exact name of the asset (case-sensitive).
- Each custom metadata set you want to include in the replacement must be a sub-object of the
businessAttributesobject. - Each custom metadata set must be specified using its hashed-string representation.
- Each custom metadata attribute you want to update must be given using its hashed-string representation.
- Additional custom metadata sets would be listed as additional sub-objects of the
businessAttributesobject. (Still using a hashed-string representation.) - ...and custom metadata attributes within those sets would be listed as sub-objects of the custom metadata set object. (Still using a hashed-string representation.)
Remove from existing asset
Remove only some custom metadata attributes
To remove only some custom metadata attributes (leaving all others unchanged):
- dbt
- Java
- Python
- Kotlin
- Raw REST API
This currently isn't possible via dbt.
CustomMetadataAttributes cmRACI = CustomMetadataAttributes.builder() // (1)
.attribute("Accountable", Removable.NULL) // (2)
.build();
Table.updateCustomMetadataAttributes( // (3)
client, // (4)
"b4113341-251b-4adc-81fb-2420501c30e6", // (5)
"RACI", // (6)
cmRACI); // (7)
-
Create a custom metadata attributes object that will contain only the attributes and values for custom metadata that you want to remove from the asset. All other custom metadata attributes (those not specified in this object) will remain unchanged on the asset.
-
For each attribute, use the
attribute()method and pass:- the name of the attribute within that set
- a special value of
Removable.NULL
This special value will make sure that the custom metadata attribute (
Accountablein this example) is removed from the asset. -
Use the
updateCustomMetadataAttributes()method to update only theAccountableattribute in theRACIcustom metadata on the existing asset. Since we're sending a special value tonullthis attribute, it will be removed by the update. Any other custom metadata attributes inRACIand all other custom metadata will be left unchanged. -
Because this operation will directly change the asset in Atlan, you must provide it an
AtlanClientthrough which to connect to the tenant. -
Note that for this operation you must know the GUID of the asset you want to remove the custom metadata from. Also, the operation returns no result: if there is an error it will throw an exception, but the result of the operation must be determined by retrieving the asset through a separate API call, if you want to confirm it.
-
Provide the name for the custom metadata you want to remove.
-
Provide the custom metadata attributes object with the attributes and special
Removable.NULLvalues you want to remove for that custom metadata.
from pyatlan.client.atlan import AtlanClient
from pyatlan.model.assets import Table
from pyatlan.model.custom_metadata import CustomMetadataDict
client = AtlanClient()
table = Table.updater( # (1)
qualified_name="default/snowflake/1657037873/SAMPLE_DB/FOOD_BEV/TOP_BEVERAGE_USERS",
name="TOP_BEVERAGE_USERS",
)
cm_raci = CustomMetadataDict( # (2)
client=client,
name="RACI", # (3)
)
cm_raci["Accountable"]= None # (4)
table.set_custom_metadata(client=client, custom_metadata=cm_raci) # (5)
response = client.asset.save_merging_cm( # (6)
table
)
assert (tables := response.assets_updated(asset_type=Table)) # (7)
-
Use the
updater()method to create an asset suitable for modifiaction that is, with all the required attributes. -
Create an instance of
CustomMetadataDict. -
Provide the name of an existing of an existing custom metadata set.
Name will be validated
The name will be validated at runtime to make sure that a custom metadata set with the given name exists.
:::
4. Set the value of the property you wish to replace to None.
The metadata property name will be validated at runtime to make sure that a property with the given name exists in the custom metadata set.
- Use the
set_custom_metadata()method to add the custom metadata to the model object. - Use the
save_merging_cm()method to update the model object on the server. - Assert that a
Tableasset has been updated.
val cmRACI = CustomMetadataAttributes.builder() // (1)
.attribute("Accountable", Removable.NULL) // (2)
.build()
Table.updateCustomMetadataAttributes( // (3)
client, // (4)
"b4113341-251b-4adc-81fb-2420501c30e6", // (5)
"RACI", // (6)
cmRACI) // (7)
-
Create a custom metadata attributes object that will contain only the attributes and values for custom metadata that you want to remove from the asset. All other custom metadata attributes (those not specified in this object) will remain unchanged on the asset.
-
For each attribute, use the
attribute()method and pass:- the name of the attribute within that set
- a special value of
Removable.NULL
This special value will make sure that the custom metadata attribute (
Accountablein this example) is removed from the asset. -
Use the
updateCustomMetadataAttributes()method to update only theAccountableattribute in theRACIcustom metadata on the existing asset. Since we're sending a special value tonullthis attribute, it will be removed by the update. Any other custom metadata attributes inRACIand all other custom metadata will be left unchanged. -
Because this operation will directly change the asset in Atlan, you must provide it an
AtlanClientthrough which to connect to the tenant. -
Note that for this operation you must know the GUID of the asset you want to remove the custom metadata from. Also, the operation returns no result: if there is an error it will throw an exception, but the result of the operation must be determined by retrieving the asset through a separate API call, if you want to confirm it.
-
Provide the name for the custom metadata you want to remove.
-
Provide the custom metadata attributes object with the attributes and special
Removable.NULLvalues you want to remove for that custom metadata.
{ // (1)
"MNJ8mpLsIOaP4OQnLNhRta": { // (2)
"xDUCZllc4JyTKhwqSDkWK4": null // (3)
}
}
- Note that the query parameters
isOverwritemust befalsein the request. This is what allows the removal of only the attributes provided in the request (and leaving all others unchanged). Also note that you must provide the GUID of the asset—there is no equivalent operation using the qualifiedName. - Each custom metadata set you want to include in the partial removal must be specified using its hashed-string representation.
- Each custom metadata attribute you want to remove must be given using its hashed-string representation, with a value of
null. You would either need to first retrieve the list of custom metadata definitions via API to determine this value, or look through the development console of your browser while opening the custom metadata in the Atlan UI.
Remove some custom metadata from asset
You can also remove an entire set of custom metadata from existing assets. If you do this individually, you can selectively remove individual sets of custom metadata:
- dbt
- Java
- Python
- Kotlin
- Raw REST API
models:
- name: TOP_BEVERAGE_USERS # (1)
meta:
atlan:
businessAttributes:
MNJ8mpLsIOaP4OQnLNhRta: {} # (2)
- You must of course give the name of the object.
- The custom metadata must be nested within the
meta.atlan.businessAttributesstructure. To remove all properties for some custom metadata, send an explicit empty dictionary{}to the custom metadata's hashed-string representation.
Table.removeCustomMetadata( // (1)
client, // (2)
"b4113341-251b-4adc-81fb-2420501c30e6", // (3)
"RACI"); // (4)
- Use the
removeCustomMetadata()method to remove an entire named set of custom metadata from an asset. Any other custom metadata in other named sets will be left unchanged. - Because this operation will directly change the asset in Atlan, you must provide it an
AtlanClientthrough which to connect to the tenant. - Note that for this operation you must know the GUID of the asset you want to remove the custom metadata from. Also, the operation returns no result: if there is an error it will throw an exception, but the result of the operation must be determined by retrieving the asset through a separate API call, if you want to confirm it.
- Provide the name for the custom metadata you want to remove.
from pyatlan.client.atlan import AtlanClient
from pyatlan.model.assets import Table
from pyatlan.model.custom_metadata import CustomMetadataDict
client = AtlanClient()
table = Table.updater( # (1)
qualified_name="default/snowflake/1657037873/SAMPLE_DB/FOOD_BEV/TOP_BEVERAGE_USERS",
name="TOP_BEVERAGE_USERS",
)
cm_raci = CustomMetadataDict( # (2)
client=client,
name="RACI", # (3)
)
table.set_custom_metadata(client=client, custom_metadata=cm_raci) # (4)
response = client.asset.save_merging_cm( # (5)
table
)
assert (tables := response.assets_updated(asset_type=Table)) # (6)
-
Use the
updater()method to create an asset suitable for modifiaction that is, with all the required attributes. -
Create a new instance of
CustomMetadataDict. -
Provide the name of an existing custom metadata set.
Name will be validated
The name will be validated at runtime to make sure that a custom metadata set with the given name exists.
:::
4. Use the set_custom_metadata() method to add the custom metadata to the model object.
5. Use the save_merging_cm() method to update the model object on the server.
6. Assert that a Table asset has been updated.
Table.removeCustomMetadata( // (1)
client, // (2)
"b4113341-251b-4adc-81fb-2420501c30e6", // (3)
"RACI") // (4)
- Use the
removeCustomMetadata()method to remove an entire named set of custom metadata from an asset. Any other custom metadata in other named sets will be left unchanged. - Because this operation will directly change the asset in Atlan, you must provide it an
AtlanClientthrough which to connect to the tenant. - Note that for this operation you must know the GUID of the asset you want to remove the custom metadata from. Also, the operation returns no result: if there is an error it will throw an exception, but the result of the operation must be determined by retrieving the asset through a separate API call, if you want to confirm it.
- Provide the name for the custom metadata you want to remove.
{ // (1)
"MNJ8mpLsIOaP4OQnLNhRta": { // (2)
"F8XI9GzcBpdBdfi4cLiPEz": null, // (3)
"xDUCZllc4JyTKhwqSDkWK4": null,
"fWMB77RSjRGNYoFeD4FcGi": null,
"rN6H6xMQpyHvo639SXER83": null
}
}
- Note that the query parameters
isOverwritemust befalsein the request. This is what allows the removal of only the custom metadata set provided in the request (and leaving all others unchanged). Also note that you must provide the GUID of the asset—there is no equivalent operation using the qualifiedName. - The custom metadata set you want to remove must be specified using its hashed-string representation.
- Each custom metadata attribute in that custom metadata set must be specified using its hashed-string representation, with a value of
null. You would either need to first retrieve the list of custom metadata definitions via API to determine this value, or look through the development console of your browser while opening the custom metadata in the Atlan UI.
Remove all custom metadata from asset
Remember that Atlan matches the provided qualifiedName to determine whether to update or create the asset.
To remove all custom metadata from an existing asset:
- dbt
- Java
- Python
- Kotlin
- Raw REST API
models:
- name: TOP_BEVERAGE_USERS # (1)
meta:
atlan:
businessAttributes: {} # (2)
- You must of course give the name of the object.
- The custom metadata must be nested within the
meta.atlan.businessAttributesstructure. To remove all custom metadata, send an explicit empty dictionary{}.
Table table = Table
.updater("default/snowflake/1657037873/SAMPLE_DB/FOOD_BEV/TOP_BEVERAGE_USERS", // (1)
"TOP_BEVERAGE_USERS").build();
AssetMutationResponse response = table.saveReplacingCM(client, false); // (2)
assert response.getUpdatedAssets().size() == 1; // (3)
- Use the
updater()method to initialize the object with all necessary attributes for updating it. (Removing the custom metadata is still an update to the asset, we'ren't deleting the asset itself.) - Call the
saveReplacingCM()method to actually update the asset, and overwrite custom metadata. Since we'ven't provided any custom metadata in our object, this will replace the existing custom metadata on the asset with no custom metadata. (In other words, it will remove all custom metadata from the asset.) Because this operation will persist the asset in Atlan, you must provide it anAtlanClientthrough which to connect to the tenant. - The response will include that single asset that was updated (again, removing custom metadata is an update to the asset—we'ren't deleting the asset itself).
from pyatlan.client.atlan import AtlanClient
from pyatlan.model.assets import Table
client = AtlanClient()
table = Table.updater( # (1)
qualified_name="default/snowflake/1657037873/SAMPLE_DB/FOOD_BEV/TOP_BEVERAGE_USERS",
name="TOP_BEVERAGE_USERS",
)
response = client.asset.save_replacing_cm( # (2)
table
)
assert (tables := response.assets_updated(asset_type=Table)) # (3)
- Use the
updater()method to initialize the object with all necessary attributes for updating it. (Removing the custom metadata is still an update to the asset, we'ren't deleting the asset itself.) - Call the
save_replacing_cm()method to actually update the asset. - Assert that a
Tableasset has been updated.
val table = Table
.updater("default/snowflake/1657037873/SAMPLE_DB/FOOD_BEV/TOP_BEVERAGE_USERS", // (1)
"TOP_BEVERAGE_USERS").build()
val response = table.saveReplacingCM(client, false) // (2)
assert(response.updatedAssets.size == 1) // (3)
- Use the
updater()method to initialize the object with all necessary attributes for updating it. (Removing the custom metadata is still an update to the asset, we'ren't deleting the asset itself.) - Call the
saveReplacingCM()method to actually update the asset, and overwrite custom metadata. Since we'ven't provided any custom metadata in our object, this will replace the existing custom metadata on the asset with no custom metadata. (In other words, it will remove all custom metadata from the asset.) Because this operation will persist the asset in Atlan, you must provide it anAtlanClientthrough which to connect to the tenant. - The response will include that single asset that was updated (again, removing custom metadata is an update to the asset—we'ren't deleting the asset itself).
{ // (1)
"entities": [ // (2) // (6)
}
]
}
- Note that the query parameters
replaceBusinessAttributesandoverwriteBusinessAttributesmust both equaltruein the request. This is what causes the replacement behavior. - All assets must be wrapped in an
entitiesarray. - You must provide the exact type name for the asset (case-sensitive).
- You must provide the exact
qualifiedNameof the asset (case-sensitive). - You must provide the exact name of the asset (case-sensitive).
- By not providing any
businessAttributesin the request, you will replace whatever custom metadata is on the asset with no custom metadata—equivalent to removing all custom metadata.
When creating asset
To add custom metadata when creating one or many assets:
- dbt
- Java
- Python
- Kotlin
- Raw REST API
models:
- name: TOP_BEVERAGE_USERS # (1)
meta:
atlan:
businessAttributes: # (2)
MNJ8mpLsIOaP4OQnLNhRta: # (3)
fWMB77RSjRGNYoFeD4FcGi: jsmith # (4)
xDUCZllc4JyTKhwqSDkWK4: jdoe
F8XI9GzcBpdBdfi4cLiPEz: [ "finance", "risk" ] # (5)
rN6H6xMQpyHvo639SXER83: [ "operations" ]
- You must of course give the name of the object.
- The custom metadata must be nested within the
meta.atlan.businessAttributesstructure. - Each custom metadata set you want to add or update must be given using its hashed-string representation.
- Each custom metadata attribute you want to update must be given using its hashed-string representation.
- For multivalued custom metadata attributes, specify the value as an array.
CustomMetadataAttributes cmRACI = CustomMetadataAttributes.builder() // (1)
.attribute("Responsible", "jsmith") // (2)
.attribute("Accountable", "jdoe")
.attribute("Consulted", List.of("finance", "risk")) // (3)
.attribute("Informed", List.of("operations"))
.build();
Table table = Table
.creator("TOP_BEVERAGE_USERS", // (4)
"default/snowflake/1657037873/SAMPLE_DB/FOOD_BEV")
.customMetadata("RACI", cmRACI) // (5)
.build(); // (6)
AssetMutationResponse response = table.saveReplacingCM(client, false); // (7)
assert response.getCreatedAssets().size() == 1 // (8)
-
Create a custom metadata attributes object that will contain the attributes and values for custom metadata you want to add to the asset.
-
For each attribute, use the
attribute()method and pass:- the name of the attribute within that set
- the value for that attribute
The value can be any object valid for the attribute: a string, a boolean, or a number. (Note that dates are sent as
long(epoch) numbers.) -
For any attribute that can be multi-valued, we can send a list of values.
-
Use the
creator()method to initialize the object with all necessary attributes for creating it. -
Set the custom metadata that should be added (using the custom metadata attributes object you built earlier).
- Note that the first parameter to this method is the name of the custom metadata for which you're providing the attributes and values.
- You can chain this
customMetadata()method as many times as you like to add other custom metadata and attributes, but you should only call it once per named custom metadata set. (If you call it multiple times for the same named custom metadata, only the last one will be applied.)
-
Call the
build()method to build the enriched object. -
Call the
saveReplacingCM()method to create the asset, including its custom metadata. (During creation you could also usesaveMergingCM(), but if you use onlysave()then no custom metadata will be attached to the assets.) Because this operation will persist the asset in Atlan, you must provide it anAtlanClientthrough which to connect to the tenant. -
The response will include all assets that were created.
from pyatlan.client.atlan import AtlanClient
from pyatlan.model.assets import Table
from pyatlan.model.custom_metadata import CustomMetadataDict
client = AtlanClient()
table = Table.creator( # (1)
schema_qualified_name="default/snowflake/1657037873/SAMPLE_DB/FOOD_BEV",
name="TOP_BEVERAGE_USERS",
)
cm_raci = CustomMetadataDict( # (2)
client=client,
name="RACI", # (3)
) #
cm_raci["Accountable"] = "jdoe" # (4)
cm_raci["Responsible"] = ["jsmith"]
cm_raci["Consulted"] = ["finance", "risk"] # (5)
cm_raci["Informed"] = ["operations"]
table.set_custom_metadata(client=client, custom_metadata=cm_raci) # (6)
response = client.asset.save(table) # (7)
assert (created := response.assets_created(asset_type=Table) # (8)
-
Use the
creator()method to initialize the object with all necessary attributes for creating it. -
Create a new instance of
CustomMetadataDict. -
Provide the name of and existing custom metadata set.
Name will be validated
The name will be validated at runtime to make sure that a custom metadata set with the given name exists. ::: 4. For each property that you want to set, specify the property name.
The metadata property name will be validated at runtime to make sure that a property with the given name exists in the custom metadata set.
- For any attribute that can be multi-valued, we need to send a list of values.
- Use the
set_custom_metadata()method to add the custom metadata to the model object. - Use the
save()method to update the model object on the server. - assert that a
Tableasset was created.
val cmRACI = CustomMetadataAttributes.builder() // (1)
.attribute("Responsible", "jsmith") // (2)
.attribute("Accountable", "jdoe")
.attribute("Consulted", listOf("finance", "risk")) // (3)
.attribute("Informed", listOf("operations"))
.build()
val table = Table
.creator("TOP_BEVERAGE_USERS", // (4)
"default/snowflake/1657037873/SAMPLE_DB/FOOD_BEV")
.customMetadata("RACI", cmRACI) // (5)
.build() // (6)
val response = table.saveReplacingCM(client, false) // (7)
assert(response.createdAssets.size == 1) // (8)
-
Create a custom metadata attributes object that will contain the attributes and values for custom metadata you want to add to the asset.
-
For each attribute, use the
attribute()method and pass:- the name of the attribute within that set
- the value for that attribute
The value can be any object valid for the attribute: a string, a boolean, or a number. (Note that dates are sent as
long(epoch) numbers.) -
For any attribute that can be multi-valued, we can send a list of values.
-
Use the
creator()method to initialize the object with all necessary attributes for creating it. -
Set the custom metadata that should be added (using the custom metadata attributes object you built earlier).
- Note that the first parameter to this method is the name of the custom metadata for which you're providing the attributes and values.
- You can chain this
customMetadata()method as many times as you like to add other custom metadata and attributes, but you should only call it once per named custom metadata set. (If you call it multiple times for the same named custom metadata, only the last one will be applied.)
-
Call the
build()method to build the enriched object. -
Call the
saveReplacingCM()method to create the asset, including its custom metadata. (During creation you could also usesaveMergingCM(), but if you use onlysave()then no custom metadata will be attached to the assets.) Because this operation will persist the asset in Atlan, you must provide it anAtlanClientthrough which to connect to the tenant. -
The response will include all assets that were created.
{
"entities": [ // (1)
}
},
"businessAttributes": { // (6)
"MNJ8mpLsIOaP4OQnLNhRta": { // (7)
"fWMB77RSjRGNYoFeD4FcGi": "jsmith", // (8)
"xDUCZllc4JyTKhwqSDkWK4": "jdoe",
"F8XI9GzcBpdBdfi4cLiPEz": [ // (9)
"finance",
"risk"
],
"rN6H6xMQpyHvo639SXER83": [
"operations"
]
}
}
}
]
}
- All assets must be wrapped in an
entitiesarray. - You must provide the exact type name for the asset (case-sensitive).
- You must provide a name for the asset.
- In the case of a table, the
qualifiedNamemust be the concatenation of the parent schema's qualifiedName and the name of the table. - When creating a table, you must specify the schema to create it within. This is defined by the
atlanSchemaattribute. You must specify both the type (must beSchema) and qualifiedName of the schema within theatlanSchemaattribute—and the schema must already exist. - Each custom metadata set you want to include on the asset must be a sub-object of the
businessAttributesobject. - Each custom metadata set must be specified using its hashed-string representation.
- Each custom metadata attribute you want to add must be given using its hashed-string representation.
- For multivalued custom metadata attributes, specify the value as an array.
Find hashed-string names
When using either the raw APIs or specifying businessAttributes with dbt, you must provide the classification names using Atlan's hashed-string representation.
Note that this isn't needed when using the SDKs, which translate these for you!
To look up the hashed-string representations:
The response will include displayName and name, both at overall custom metadata level and for each attribute (property). The displayName is what you see in Atlan's UI, and the name is the hashed-string representation:
{
"enumDefs": [],
"structDefs": [],
"classificationDefs": [],
"entityDefs": [],
"relationshipDefs": [],
"businessMetadataDefs": [
{
"category": "BUSINESS_METADATA",
"guid": "e5cc3476-9cd9-4ed7-89a7-18dfde86f827",
"name": "MNJ8mpLsIOaP4OQnLNhRta",
"displayName": "RACI",
"options": {
"logoType": "emoji",
"emoji": "👪"
},
"attributeDefs": [
{
"name": "fWMB77RSjRGNYoFeD4FcGi",
"displayName": "Responsible",
"cardinality": "SINGLE",
"typeName": "string",
"description": "",
"options": {
"customType": "users",
"showInOverview": "false",
"allowFiltering": "true",
"isEnum": "false",
"multiValueSelect": "false",
"primitiveType": "users"
}
},
{
"name": "xDUCZllc4JyTKhwqSDkWK4",
"displayName": "Accountable",
"cardinality": "SINGLE",
"typeName": "string",
"description": "",
"options": {
"customType": "users",
"showInOverview": "false",
"allowFiltering": "true",
"isEnum": "false",
"multiValueSelect": "false",
"primitiveType": "users"
}
},
{
"name": "F8XI9GzcBpdBdfi4cLiPEz",
"displayName": "Consulted",
"typeName": "array<string>",
"cardinality": "SET",
"description": "",
"options": {
"customType": "groups",
"showInOverview": "false",
"allowFiltering": "true",
"isEnum": "false",
"multiValueSelect": "true",
"primitiveType": "groups"
}
},
{
"name": "rN6H6xMQpyHvo639SXER83",
"displayName": "Informed",
"typeName": "array<string>",
"cardinality": "SET",
"description": "",
"options": {
"customType": "groups",
"showInOverview": "false",
"allowFiltering": "true",
"isEnum": "false",
"multiValueSelect": "true",
"primitiveType": "groups"
}
},
{
"name": "okm7BDXjTQx4iYPT5u7ilu",
"displayName": "Extra",
"typeName": "string",
"cardinality": "SINGLE",
"description": "",
"options": {
"showInOverview": "false",
"allowFiltering": "true",
"isEnum": "false",
"multiValueSelect": "false",
"primitiveType": "string"
}
}
]
},
{
"category": "BUSINESS_METADATA",
"guid": "389c0f8a-5d68-407c-8b5c-45a19f2cc7e0",
"name": "foMg7yOwUajucuya0JEF4J",
"displayName": "Other",
"options": {
"logoType": "emoji",
"emoji": "❓"
},
"attributeDefs": [
{
"name": "uTmK5o0J8jHTH3KWFXXeZi",
"displayName": "Another",
"typeName": "string",
"cardinality": "SINGLE",
"description": "",
"options": {
"showInOverview": "false",
"allowFiltering": "true",
"isEnum": "false",
"multiValueSelect": "false",
"primitiveType": "string"
}
}
]
}
]
}