PUT /v1/tables/{id}/customMetric
from metadata.sdk import configure, client
from metadata.sdk.entities import Tables
from metadata.generated.schema.api.tests.createCustomMetric import CreateCustomMetricRequest
configure(
host="https://your-company.open-metadata.org/api",
jwt_token="your-jwt-token"
)
rest = client().ometa.client
table_id = "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
# Add a table-level custom metric
Tables.add_custom_metric(table_id, CreateCustomMetricRequest(
name="active_customer_ratio",
description="Ratio of active customers to total customers",
expression="SELECT CAST(SUM(CASE WHEN active = true THEN 1 ELSE 0 END) AS FLOAT) / COUNT(*) FROM {table}"
))
# Add a column-level custom metric
Tables.add_custom_metric(table_id, CreateCustomMetricRequest(
name="email_domain_count",
description="Number of distinct email domains",
columnName="email",
expression="SELECT COUNT(DISTINCT SPLIT_PART(email, '@', 2)) FROM {table}"
))
# Delete a table-level custom metric
rest.delete(f"/tables/{table_id}/customMetric/active_customer_ratio")
# Delete a column-level custom metric
rest.delete(f"/tables/{table_id}/customMetric/email/email_domain_count")
import org.openmetadata.schema.tests.CustomMetric;
// client is an initialized OpenMetadataClient.
String tableId = "a1b2c3d4-e5f6-7890-abcd-ef1234567890";
// Add a table-level custom metric
CustomMetric tableMetric = new CustomMetric()
.withName("active_customer_ratio")
.withDescription("Ratio of active customers to total customers")
.withExpression("SELECT CAST(SUM(CASE WHEN active = true THEN 1 ELSE 0 END) AS FLOAT) / COUNT(*) FROM {table}");
client.tables().updateCustomMetric(tableId, tableMetric);
// Add a column-level custom metric
CustomMetric columnMetric = new CustomMetric()
.withName("email_domain_count")
.withDescription("Number of distinct email domains")
.withColumnName("email")
.withExpression("SELECT COUNT(DISTINCT SPLIT_PART(email, '@', 2)) FROM {table}");
client.tables().updateCustomMetric(tableId, columnMetric);
// Delete a table-level custom metric
client.tables().deleteCustomMetric(tableId, "active_customer_ratio");
// Delete a column-level custom metric
client.tables().deleteCustomMetric(tableId, "email/email_domain_count");
# Add a table-level custom metric
curl -X PUT "{base_url}/api/v1/tables/455e3d9d-dbbf-455e-b3be-7191daa825f3/customMetric" \
-H "Authorization: Bearer {access_token}" \
-H "Content-Type: application/json" \
-d '{
"name": "high_performer_ratio",
"description": "Ratio of high-performing agents (score > 90) to total agents",
"expression": "SELECT CAST(SUM(CASE WHEN performance_score > 90 THEN 1 ELSE 0 END) AS FLOAT) / COUNT(*) FROM {table}"
}'
# Add a column-level custom metric
curl -X PUT "{base_url}/api/v1/tables/455e3d9d-dbbf-455e-b3be-7191daa825f3/customMetric" \
-H "Authorization: Bearer {access_token}" \
-H "Content-Type: application/json" \
-d '{
"name": "avg_performance",
"description": "Average performance score across all agents",
"columnName": "performance_score",
"expression": "SELECT AVG(performance_score) FROM {table}"
}'
# Delete a custom metric
curl -X DELETE "{base_url}/api/v1/tables/455e3d9d-dbbf-455e-b3be-7191daa825f3/customMetric/high_performer_ratio" \
-H "Authorization: Bearer {access_token}"
{
"id": "455e3d9d-dbbf-455e-b3be-7191daa825f3",
"name": "agent_performance_summary",
"fullyQualifiedName": "sample_data.ecommerce_db.shopify.agent_performance_summary",
"customMetrics": [
{
"name": "high_performer_ratio",
"description": "Ratio of high-performing agents (score > 90) to total agents",
"expression": "SELECT CAST(SUM(CASE WHEN performance_score > 90 THEN 1 ELSE 0 END) AS FLOAT) / COUNT(*) FROM {table}"
}
]
}
Table Custom Metrics API
Add and delete custom metrics for tables
PUT
/
v1
/
tables
/
{id}
/
customMetric
PUT /v1/tables/{id}/customMetric
from metadata.sdk import configure, client
from metadata.sdk.entities import Tables
from metadata.generated.schema.api.tests.createCustomMetric import CreateCustomMetricRequest
configure(
host="https://your-company.open-metadata.org/api",
jwt_token="your-jwt-token"
)
rest = client().ometa.client
table_id = "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
# Add a table-level custom metric
Tables.add_custom_metric(table_id, CreateCustomMetricRequest(
name="active_customer_ratio",
description="Ratio of active customers to total customers",
expression="SELECT CAST(SUM(CASE WHEN active = true THEN 1 ELSE 0 END) AS FLOAT) / COUNT(*) FROM {table}"
))
# Add a column-level custom metric
Tables.add_custom_metric(table_id, CreateCustomMetricRequest(
name="email_domain_count",
description="Number of distinct email domains",
columnName="email",
expression="SELECT COUNT(DISTINCT SPLIT_PART(email, '@', 2)) FROM {table}"
))
# Delete a table-level custom metric
rest.delete(f"/tables/{table_id}/customMetric/active_customer_ratio")
# Delete a column-level custom metric
rest.delete(f"/tables/{table_id}/customMetric/email/email_domain_count")
import org.openmetadata.schema.tests.CustomMetric;
// client is an initialized OpenMetadataClient.
String tableId = "a1b2c3d4-e5f6-7890-abcd-ef1234567890";
// Add a table-level custom metric
CustomMetric tableMetric = new CustomMetric()
.withName("active_customer_ratio")
.withDescription("Ratio of active customers to total customers")
.withExpression("SELECT CAST(SUM(CASE WHEN active = true THEN 1 ELSE 0 END) AS FLOAT) / COUNT(*) FROM {table}");
client.tables().updateCustomMetric(tableId, tableMetric);
// Add a column-level custom metric
CustomMetric columnMetric = new CustomMetric()
.withName("email_domain_count")
.withDescription("Number of distinct email domains")
.withColumnName("email")
.withExpression("SELECT COUNT(DISTINCT SPLIT_PART(email, '@', 2)) FROM {table}");
client.tables().updateCustomMetric(tableId, columnMetric);
// Delete a table-level custom metric
client.tables().deleteCustomMetric(tableId, "active_customer_ratio");
// Delete a column-level custom metric
client.tables().deleteCustomMetric(tableId, "email/email_domain_count");
# Add a table-level custom metric
curl -X PUT "{base_url}/api/v1/tables/455e3d9d-dbbf-455e-b3be-7191daa825f3/customMetric" \
-H "Authorization: Bearer {access_token}" \
-H "Content-Type: application/json" \
-d '{
"name": "high_performer_ratio",
"description": "Ratio of high-performing agents (score > 90) to total agents",
"expression": "SELECT CAST(SUM(CASE WHEN performance_score > 90 THEN 1 ELSE 0 END) AS FLOAT) / COUNT(*) FROM {table}"
}'
# Add a column-level custom metric
curl -X PUT "{base_url}/api/v1/tables/455e3d9d-dbbf-455e-b3be-7191daa825f3/customMetric" \
-H "Authorization: Bearer {access_token}" \
-H "Content-Type: application/json" \
-d '{
"name": "avg_performance",
"description": "Average performance score across all agents",
"columnName": "performance_score",
"expression": "SELECT AVG(performance_score) FROM {table}"
}'
# Delete a custom metric
curl -X DELETE "{base_url}/api/v1/tables/455e3d9d-dbbf-455e-b3be-7191daa825f3/customMetric/high_performer_ratio" \
-H "Authorization: Bearer {access_token}"
{
"id": "455e3d9d-dbbf-455e-b3be-7191daa825f3",
"name": "agent_performance_summary",
"fullyQualifiedName": "sample_data.ecommerce_db.shopify.agent_performance_summary",
"customMetrics": [
{
"name": "high_performer_ratio",
"description": "Ratio of high-performing agents (score > 90) to total agents",
"expression": "SELECT CAST(SUM(CASE WHEN performance_score > 90 THEN 1 ELSE 0 END) AS FLOAT) / COUNT(*) FROM {table}"
}
]
}
Custom Metrics
Define custom SQL-based metrics on a table or specific column. Custom metrics are evaluated during profiling runs and tracked over time.Add Custom Metric
PUT /v1/tables/{id}/customMetric
Delete Custom Metric
DELETE /v1/tables/{id}/customMetric/{metricName}
To delete a column-level metric, use DELETE /v1/tables/{id}/customMetric/{columnName}/{metricName}.
PUT /v1/tables/{id}/customMetric
from metadata.sdk import configure, client
from metadata.sdk.entities import Tables
from metadata.generated.schema.api.tests.createCustomMetric import CreateCustomMetricRequest
configure(
host="https://your-company.open-metadata.org/api",
jwt_token="your-jwt-token"
)
rest = client().ometa.client
table_id = "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
# Add a table-level custom metric
Tables.add_custom_metric(table_id, CreateCustomMetricRequest(
name="active_customer_ratio",
description="Ratio of active customers to total customers",
expression="SELECT CAST(SUM(CASE WHEN active = true THEN 1 ELSE 0 END) AS FLOAT) / COUNT(*) FROM {table}"
))
# Add a column-level custom metric
Tables.add_custom_metric(table_id, CreateCustomMetricRequest(
name="email_domain_count",
description="Number of distinct email domains",
columnName="email",
expression="SELECT COUNT(DISTINCT SPLIT_PART(email, '@', 2)) FROM {table}"
))
# Delete a table-level custom metric
rest.delete(f"/tables/{table_id}/customMetric/active_customer_ratio")
# Delete a column-level custom metric
rest.delete(f"/tables/{table_id}/customMetric/email/email_domain_count")
import org.openmetadata.schema.tests.CustomMetric;
// client is an initialized OpenMetadataClient.
String tableId = "a1b2c3d4-e5f6-7890-abcd-ef1234567890";
// Add a table-level custom metric
CustomMetric tableMetric = new CustomMetric()
.withName("active_customer_ratio")
.withDescription("Ratio of active customers to total customers")
.withExpression("SELECT CAST(SUM(CASE WHEN active = true THEN 1 ELSE 0 END) AS FLOAT) / COUNT(*) FROM {table}");
client.tables().updateCustomMetric(tableId, tableMetric);
// Add a column-level custom metric
CustomMetric columnMetric = new CustomMetric()
.withName("email_domain_count")
.withDescription("Number of distinct email domains")
.withColumnName("email")
.withExpression("SELECT COUNT(DISTINCT SPLIT_PART(email, '@', 2)) FROM {table}");
client.tables().updateCustomMetric(tableId, columnMetric);
// Delete a table-level custom metric
client.tables().deleteCustomMetric(tableId, "active_customer_ratio");
// Delete a column-level custom metric
client.tables().deleteCustomMetric(tableId, "email/email_domain_count");
# Add a table-level custom metric
curl -X PUT "{base_url}/api/v1/tables/455e3d9d-dbbf-455e-b3be-7191daa825f3/customMetric" \
-H "Authorization: Bearer {access_token}" \
-H "Content-Type: application/json" \
-d '{
"name": "high_performer_ratio",
"description": "Ratio of high-performing agents (score > 90) to total agents",
"expression": "SELECT CAST(SUM(CASE WHEN performance_score > 90 THEN 1 ELSE 0 END) AS FLOAT) / COUNT(*) FROM {table}"
}'
# Add a column-level custom metric
curl -X PUT "{base_url}/api/v1/tables/455e3d9d-dbbf-455e-b3be-7191daa825f3/customMetric" \
-H "Authorization: Bearer {access_token}" \
-H "Content-Type: application/json" \
-d '{
"name": "avg_performance",
"description": "Average performance score across all agents",
"columnName": "performance_score",
"expression": "SELECT AVG(performance_score) FROM {table}"
}'
# Delete a custom metric
curl -X DELETE "{base_url}/api/v1/tables/455e3d9d-dbbf-455e-b3be-7191daa825f3/customMetric/high_performer_ratio" \
-H "Authorization: Bearer {access_token}"
{
"id": "455e3d9d-dbbf-455e-b3be-7191daa825f3",
"name": "agent_performance_summary",
"fullyQualifiedName": "sample_data.ecommerce_db.shopify.agent_performance_summary",
"customMetrics": [
{
"name": "high_performer_ratio",
"description": "Ratio of high-performing agents (score > 90) to total agents",
"expression": "SELECT CAST(SUM(CASE WHEN performance_score > 90 THEN 1 ELSE 0 END) AS FLOAT) / COUNT(*) FROM {table}"
}
]
}
Returns
Add returns the updated table object with the custom metric included. Delete returns no content (204).Response
Error Handling
| Code | Error Type | Description |
|---|---|---|
401 | UNAUTHORIZED | Invalid or missing authentication token |
403 | FORBIDDEN | User lacks permission |
404 | NOT_FOUND | Table or custom metric does not exist |
400 | BAD_REQUEST | Invalid metric definition or SQL expression |
409 | CONFLICT | Custom metric with same name already exists |
Was this page helpful?