Data Catalog is deprecated and will be discontinued on January 30, 2026. For steps to transition your Data Catalog users, workloads, and content to Dataplex Universal Catalog, seeTransition from Data Catalog to Dataplex Universal Catalog.
Create custom Data Catalog entries for your data sources
Stay organized with collectionsSave and categorize content based on your preferences.
This document describes how to create custom Data Catalog entries.
To integrate your custom data sources, call Data Catalog
APIs that allow you to create and manage Data Catalog entries
with custom data resource types. In this document, an entry for a custom data
resource type is referred to as a "custom entry".
Create entry groups and custom entries
Custom entries must be placed within a user-created entry group. You
create the entry group, then create the custom entry within the entry group.
For more information, seeEntries and entry groups.
After creating an entry, you canset IAM policieson the entry group to define who has access to the entry group and the entries inside.
importcom.google.cloud.datacatalog.v1.ColumnSchema;importcom.google.cloud.datacatalog.v1.CreateEntryGroupRequest;importcom.google.cloud.datacatalog.v1.CreateEntryRequest;importcom.google.cloud.datacatalog.v1.DataCatalogClient;importcom.google.cloud.datacatalog.v1.Entry;importcom.google.cloud.datacatalog.v1.EntryGroup;importcom.google.cloud.datacatalog.v1.LocationName;importcom.google.cloud.datacatalog.v1.Schema;importjava.io.IOException;// Sample to create custom entrypublicclassCreateCustomEntry{publicstaticvoidmain(String[]args)throwsIOException{// TODO(developer): Replace these variables before running the sample.StringprojectId="my-project";StringentryGroupId="onprem_entry_group";StringentryId="onprem_entry_id";createCustomEntry(projectId,entryGroupId,entryId);}publicstaticvoidcreateCustomEntry(StringprojectId,StringentryGroupId,StringentryId)throwsIOException{// Currently, Data Catalog stores metadata in the us-central1 region.Stringlocation="us-central1";// Initialize client that will be used to send requests. This client only needs to be created// once, and can be reused for multiple requests. After completing all of your requests, call// the "close" method on the client to safely clean up any remaining background resources.try(DataCatalogClientdataCatalogClient=DataCatalogClient.create()){// Construct the EntryGroup for the EntryGroup request.EntryGroupentryGroup=EntryGroup.newBuilder().setDisplayName("My awesome Entry Group").setDescription("This Entry Group represents an external system").build();// Construct the EntryGroup request to be sent by the client.CreateEntryGroupRequestentryGroupRequest=CreateEntryGroupRequest.newBuilder().setParent(LocationName.of(projectId,location).toString()).setEntryGroupId(entryGroupId).setEntryGroup(entryGroup).build();// Use the client to send the API request.EntryGroupcreatedEntryGroup=dataCatalogClient.createEntryGroup(entryGroupRequest);// Construct the Entry for the Entry request.Entryentry=Entry.newBuilder().setUserSpecifiedSystem("onprem_data_system").setUserSpecifiedType("onprem_data_asset").setDisplayName("My awesome data asset").setDescription("This data asset is managed by an external system.").setLinkedResource("//my-onprem-server.com/dataAssets/my-awesome-data-asset").setSchema(Schema.newBuilder().addColumns(ColumnSchema.newBuilder().setColumn("first_column").setDescription("This columns consists of ....").setMode("NULLABLE").setType("DOUBLE").build()).addColumns(ColumnSchema.newBuilder().setColumn("second_column").setDescription("This columns consists of ....").setMode("REQUIRED").setType("STRING").build()).build()).build();// Construct the Entry request to be sent by the client.CreateEntryRequestentryRequest=CreateEntryRequest.newBuilder().setParent(createdEntryGroup.getName()).setEntryId(entryId).setEntry(entry).build();// Use the client to send the API request.EntrycreatedEntry=dataCatalogClient.createEntry(entryRequest);System.out.printf("Custom entry created with name: %s",createdEntry.getName());}}}
// Import the Google Cloud client library.const{DataCatalogClient}=require('@google-cloud/datacatalog').v1;constdatacatalog=newDataCatalogClient();asyncfunctioncreateCustomEntry(){// Create a custom entry within an entry group./*** TODO(developer): Uncomment the following lines before running the sample.*/// const projectId = 'my_project';// const entryGroupId = 'my_entry_group';// const entryId = 'my_entry';// const tagTemplateId = 'my_tag_template';// Currently, Data Catalog stores metadata in the us-central1 region.constlocation='us-central1';// Delete any pre-existing Entry with the same name// that will be used to create the new Entry.try{constentryName=datacatalog.entryPath(projectId,location,entryGroupId,entryId);awaitdatacatalog.deleteEntry({name:entryName});console.log(`Deleted Entry:${entryName}`);}catch(err){console.log('Entry does not exist.');}// Delete any pre-existing Entry Group with the same name// that will be used to construct the new EntryGroup.try{constentryGroupName=datacatalog.entryGroupPath(projectId,location,entryGroupId);awaitdatacatalog.deleteEntryGroup({name:entryGroupName});console.log(`Deleted Entry Group:${entryGroupName}`);}catch(err){console.log('Entry Group does not exist.');}// Delete any pre-existing Template with the same name// that will be used to create a new Template.consttagTemplateName=datacatalog.tagTemplatePath(projectId,location,tagTemplateId);lettagTemplateRequest={name:tagTemplateName,force:true,};try{awaitdatacatalog.deleteTagTemplate(tagTemplateRequest);console.log(`Deleted template:${tagTemplateName}`);}catch(error){console.log(`Cannot delete template:${tagTemplateName}`);}// Construct the EntryGroup for the EntryGroup request.constentryGroup={displayName:'My awesome Entry Group',description:'This Entry Group represents an external system',};// Construct the EntryGroup request to be sent by the client.constentryGroupRequest={parent:datacatalog.locationPath(projectId,location),entryGroupId:entryGroupId,entryGroup:entryGroup,};// Use the client to send the API request.const[createdEntryGroup]=awaitdatacatalog.createEntryGroup(entryGroupRequest);console.log(`Created entry group:${createdEntryGroup.name}`);// Construct the Entry for the Entry request.constentry={userSpecifiedSystem:'onprem_data_system',userSpecifiedType:'onprem_data_asset',displayName:'My awesome data asset',description:'This data asset is managed by an external system.',linkedResource:'//my-onprem-server.com/dataAssets/my-awesome-data-asset',schema:{columns:[{column:'first_column',description:'This columns consists of ....',mode:'NULLABLE',type:'STRING',},{column:'second_column',description:'This columns consists of ....',mode:'NULLABLE',type:'DOUBLE',},],},};// Construct the Entry request to be sent by the client.constentryRequest={parent:datacatalog.entryGroupPath(projectId,location,entryGroupId),entryId:entryId,entry:entry,};// Use the client to send the API request.const[createdEntry]=awaitdatacatalog.createEntry(entryRequest);console.log(`Created entry:${createdEntry.name}`);// Create a Tag Template.// For more field types, including ENUM, please refer to// https://cloud.google.com/data-catalog/docs/quickstarts/quickstart-search-tag#data-catalog-quickstart-nodejs.constfieldSource={displayName:'Source of data asset',type:{primitiveType:'STRING',},};consttagTemplate={displayName:'Demo Tag Template',fields:{source:fieldSource,},};tagTemplateRequest={parent:datacatalog.locationPath(projectId,location),tagTemplateId:tagTemplateId,tagTemplate:tagTemplate,};// Use the client to send the API request.const[createdTagTemplate]=awaitdatacatalog.createTagTemplate(tagTemplateRequest);console.log(`Created template:${createdTagTemplate.name}`);// Attach a Tag to the custom Entry.consttag={template:createdTagTemplate.name,fields:{source:{stringValue:'On-premises system name',},},};consttagRequest={parent:createdEntry.name,tag:tag,};// Use the client to send the API request.const[createdTag]=awaitdatacatalog.createTag(tagRequest);console.log(`Created tag:${createdTag.name}`);}createCustomEntry();
# Import required modules.fromgoogle.cloudimportdatacatalog_v1# Google Cloud Platform project.project_id="my-project"# Entry Group to be created.entry_group_id="my_new_entry_group_id"# Entry to be created.entry_id="my_new_entry_id"# Currently, Data Catalog stores metadata in the us-central1 region.location="us-central1"datacatalog=datacatalog_v1.DataCatalogClient()# Create an Entry Group.entry_group_obj=datacatalog_v1.types.EntryGroup()entry_group_obj.display_name="My awesome Entry Group"entry_group_obj.description="This Entry Group represents an external system"entry_group=datacatalog.create_entry_group(parent=datacatalog_v1.DataCatalogClient.common_location_path(project_id,location),entry_group_id=entry_group_id,entry_group=entry_group_obj,)entry_group_name=entry_group.nameprint("Created entry group:{}".format(entry_group_name))# Create an Entry.entry=datacatalog_v1.types.Entry()entry.user_specified_system="onprem_data_system"entry.user_specified_type="onprem_data_asset"entry.display_name="My awesome data asset"entry.description="This data asset is managed by an external system."entry.linked_resource="//my-onprem-server.com/dataAssets/my-awesome-data-asset"# Create the Schema, this is optional.entry.schema.columns.append(datacatalog_v1.types.ColumnSchema(column="first_column",type_="STRING",description="This columns consists of ....",mode=None,))entry.schema.columns.append(datacatalog_v1.types.ColumnSchema(column="second_column",type_="DOUBLE",description="This columns consists of ....",mode=None,))entry=datacatalog.create_entry(parent=entry_group_name,entry_id=entry_id,entry=entry)print("Created entry:{}".format(entry.name))
Before using any of the request data,
make the following replacements:
project_id: Your Google Cloud project ID.
entryGroupId:
ID of the existing entryGroup. The entry will be created in this EntryGroup.
entryId:
ID of the new entry. The ID must begin with a letter or underscore,
contain only English letters, numbers and underscores, and have at
most 64 characters.
userSpecifiedType:
Custom type name. The type name must begin with a letter or
underscore, must only contain letters, numbers, and underscores,
and must have at most 64 characters.
userSpecifiedSystem:
The entry's non-Google Cloud source system, which is notintegrated with Data Catalog.
The source system name must begin with a letter or
underscore, must only contain letters, numbers, and underscores,
and must have at most 64 characters.
linkedResource:
Optional fullname of the resource the entry refers to.
[[["Easy to understand","easyToUnderstand","thumb-up"],["Solved my problem","solvedMyProblem","thumb-up"],["Other","otherUp","thumb-up"]],[["Hard to understand","hardToUnderstand","thumb-down"],["Incorrect information or sample code","incorrectInformationOrSampleCode","thumb-down"],["Missing the information/samples I need","missingTheInformationSamplesINeed","thumb-down"],["Other","otherDown","thumb-down"]],["Last updated 2025-09-04 UTC."],[[["\u003cp\u003eThis document provides instructions on how to create custom entries within the Data Catalog using its APIs to integrate unique data sources.\u003c/p\u003e\n"],["\u003cp\u003eCustom entries must be created inside user-defined entry groups, which are also created via API calls before the custom entry itself.\u003c/p\u003e\n"],["\u003cp\u003eThe document includes code examples in Java, Node.js, and Python to demonstrate the process of creating entry groups and custom entries, as well as setting up authentication.\u003c/p\u003e\n"],["\u003cp\u003eInstructions for using REST API and the command line to create entry groups and custom entries within them are provided, including examples of JSON requests and responses.\u003c/p\u003e\n"],["\u003cp\u003eAfter creating custom entries, you can manage who has access to them by setting IAM policies on the entry groups that contain them.\u003c/p\u003e\n"]]],[],null,[]]