in marketing-analytics/activation/data-tasks-coordinator/src/tasks/bigquery/load_task.js [242:288]
async getSchemaForExternal_(destination, metadata, sourceFile) {
if (destination.schemaSource) {
this.logger.debug('External schema from report: ',
destination.schemaSource);
const taskConfig = await this.options.taskConfigDao.load(
destination.schemaSource);
const task = new ReportTask(taskConfig, this.parameters);
task.injectContext(this.options);
return this.getSchemaFromReportTask_(task);
}
if (destination.schemaFile) {
this.logger.debug('External schema from file: ', destination.schemaFile);
const schemaFile = StorageFile.getInstance(
destination.schemaFile.bucket, destination.schemaFile.name,
{projectId: this.getCloudProject(destination.schemaFile)});
return JSON.parse(await schemaFile.loadContent());
}
if (destination.csvSafeColumnNames) {
if (metadata.compression
|| metadata.sourceFormat.toUpperCase() !== 'CSV') {
this.logger.error('Can not figure column names for', metadata);
} else {
/** @const {StorageFile} */
const storageFile = StorageFile.getInstance(
sourceFile.bucket, sourceFile.name,
{ projectId: this.getCloudProject(sourceFile) });
// Get first 100k bytes. This should be enough to cover the first line.
const partialContent = await storageFile.loadContent(0, 100_000);
const headers = partialContent.split('\n')[0]
.split(metadata.fieldDelimiter || ',');
const fields = headers.map((header) => {
// replace all characters (expect digits, letters and underscore) with
// an underscore; add a leading underscore if it starts with a digit.
const name = header.trim().replace(/[^a-zA-Z0-9_]/g, '_')
.replace(/^([0-9])/, '_$1');
return {
name,
type: 'STRING',
mode: 'NULLABLE',
}
})
return { fields };
}
}
throw new Error('Not schema defined in config or externally');
}