How to upload and load data into a Data Commons Platform instance
Upload an exported data bundle to Google Cloud Storage, then trigger the Data Commons Platform (DCP) job that loads it into your custom knowledge graph and serves it.
Before you start
-
A Data Commons Platform instance with the DCP ingestion pipeline already deployed.
dcp-toolsdoesn't provision instances. Follow Google's guide to deploying a custom instance ↗ first. -
An exported bundle: a local directory holding
config.json, your CSV data files, and any.mcffiles, built withCustomDataManager.export_all(see Preparing data). -
The settings
dcp-toolsneeds to reach GCP and your load job, gathered into aKGSettingsobject: -
local_path(LOCAL_PATH): local directory to export and upload. This is the bundle directory from the step above. gcp_project_id(GCP_PROJECT_ID): your GCP project ID.gcp_credentials(GCP_CREDENTIALS, optional): GCP service account credentials as a JSON string. Leave unset to use Application Default Credentials (aftergcloud auth application-default login).gcs_bucket_name(GCS_BUCKET_NAME): the Cloud Storage bucket the DCP pipeline reads from.gcs_input_folder_path(GCS_INPUT_FOLDER_PATH, optional): folder in that bucket to upload the bundle to. Defaults toingestion/input, the DCP Terraform default.gcs_output_folder_path(GCS_OUTPUT_FOLDER_PATH): folder the pipeline writes its output to.load_job_region(LOAD_JOB_REGION): region of the Cloud Run load job.load_job_name(LOAD_JOB_NAME): name of the Cloud Run load job.ingestion_workflow_name(INGESTION_WORKFLOW_NAME): name of the Cloud Workflow that runs the ingestion.load_job_service_account(LOAD_JOB_SERVICE_ACCOUNT, optional): service account to impersonate when triggering the workflow. Leave unset to use your own credentials.
Steps
- Build a
KGSettingsobject.dcp-toolsreads these settings throughKGSettings, apydantic-settingsmodel. Build one from a.envfile, a JSON file, or directly, whichever fits how you manage secrets.
from dcp_tools.gcp_utilities import get_kg_settings
settings = get_kg_settings(source="env", env_file="customDC.env")
from dcp_tools.gcp_utilities import get_kg_settings
settings = get_kg_settings(source="json", file="customDC.json")
customDC.json uses the same names as the environment variables:
{
"LOCAL_PATH": "path/to/output/folder",
"GCP_PROJECT_ID": "one-campaign-dc",
"GCS_BUCKET_NAME": "one-campaign-dc-custom-data",
"GCS_INPUT_FOLDER_PATH": "customdc/input",
"GCS_OUTPUT_FOLDER_PATH": "customdc/output",
"LOAD_JOB_REGION": "us-central1",
"LOAD_JOB_NAME": "dc-load-job",
"INGESTION_WORKFLOW_NAME": "dc-load-workflow"
}
from pathlib import Path
from dcp_tools.gcp_utilities import KGSettings
settings = KGSettings(
LOCAL_PATH=Path("path/to/output/folder"),
GCP_PROJECT_ID="one-campaign-dc",
GCS_BUCKET_NAME="one-campaign-dc-custom-data",
GCS_INPUT_FOLDER_PATH="customdc/input",
GCS_OUTPUT_FOLDER_PATH="customdc/output",
LOAD_JOB_REGION="us-central1",
LOAD_JOB_NAME="dc-load-job",
INGESTION_WORKFLOW_NAME="dc-load-workflow",
)
Using the CLI instead of the Python API? Skip building a KGSettings object yourself and pass --env-file customDC.env or --settings-file customDC.json to any of the commands in the next two steps.
- Upload the bundle to Cloud Storage. This pushes every
.csv,.json, and.mcffile undersettings.local_pathtogs://<gcs_bucket_name>/<gcs_input_folder_path>/, preserving the directory structure. Other file types are skipped with a warning.
from dcp_tools.gcp_utilities import upload_to_cloud_storage
upload_to_cloud_storage(settings=settings)
Pass sync=True (Python) or --sync (CLI) to also delete remote files that no longer have a local counterpart. This is useful when you've removed or renamed a CSV since the last upload. Sync only prunes import subdirectories that are present locally. It won't touch an import that isn't in your local bundle at all.
- Trigger ingestion. This starts the DCP ingestion workflow against whatever is currently in
gcs_input_folder_path.
from dcp_tools.gcp_utilities import run_data_load
run_data_load(settings=settings) # every import
run_data_load(settings=settings, imports="climateFinance") # one import
To upload and trigger ingestion in one call, use pipeline instead of running upload and dataload separately:
pipeline always loads every import. It has no --imports flag. If you need to load a subset, run upload then dataload --imports=... separately.
run_data_load returns as soon as the workflow execution starts. It doesn't wait for it to finish. Under the hood it calls datacommons-admin's IngestionJobClient, which starts the Cloud Workflow (ingestion_workflow_name) that ingests the uploaded data and serves it automatically. There's nothing further to trigger from dcp-tools.
Note
Older versions of this package required a separate redeploy call after the load job, plus a set of CLOUD_SQL_* settings to reach the underlying database. Both are gone. The DCP prep job now owns the restart, and there's no Cloud SQL in the current architecture.
Verify it worked
Compare what's registered in config.json against what actually landed in the bucket:
import json
from pathlib import Path
from dcp_tools.gcp_utilities import get_missing_csv_files, get_unregistered_csv_files
from dcp_tools.gcp_utilities.clients import get_gcs_client
config = json.loads(Path("path/to/output/folder/config.json").read_text())
bucket = get_gcs_client(settings.gcp_credentials).get_bucket(settings.gcs_bucket_name)
print(get_missing_csv_files(bucket, config, gcs_folder_name=settings.gcs_input_folder_path))
print(get_unregistered_csv_files(bucket, config, gcs_folder_name=settings.gcs_input_folder_path))
Both should return []. A non-empty get_missing_csv_files result means a file the config expects never made it to GCS (upload failed, or it ran against the wrong folder). A non-empty get_unregistered_csv_files result means there's a stray CSV in the bucket that no inputFiles entry points at.
Ingestion itself runs as a Cloud Workflow execution (ingestion_workflow_name in load_job_region). Its run history and logs are visible in the Google Cloud Console under Workflows, not through dcp-tools.
Troubleshooting
KGSettings/get_kg_settingsraises apydantic.ValidationErrorlisting several fields as "Field required". One or more required settings are missing from your.env/JSON file, or weren't passed to the constructor. Every field exceptgcp_credentials,gcs_input_folder_path, andload_job_service_accountis required. Check the list under Before you start.GCP_CREDENTIALSraisesInvalid JSON.gcp_credentialsexpects the contents of a service-account key as a JSON string, not a file path. Read the key file and pass its contents (Path("key.json").read_text()), or leave the setting unset to use Application Default Credentials.get_missing_csv_filesreports every registered CSV as missing, even though the upload succeeded. Both functions treat agcs_folder_namethat doesn't match anything in the bucket as an empty folder rather than raising:get_missing_csv_filesthen reports everyinputFilesentry as missing, andget_unregistered_csv_filesreports nothing (there's nothing to compare against). Checkgcs_input_folder_pathfor a typo, or confirm the upload step ran first. Leading and trailing slashes are stripped automatically, so those aren't the issue.run_data_loadraisesRuntimeError: Failed to start data load job: .... The underlyingIngestionJobClientcall failed, most often from a wrongingestion_workflow_name/load_job_name/load_job_region, or aload_job_service_accountthat isn't allowed to invoke the workflow.
See also
- Preparing data: build the
config.json, CSV, and MCF bundle before uploading it. - CLI tools: full flag reference for
upload,dataload, andpipeline.