Skip to content
This repository has been archived by the owner on Aug 16, 2023. It is now read-only.

Commit

Permalink
Add table replace mode
Browse files Browse the repository at this point in the history
Change-Id: I1f66c445413b89e53b69e81deb2b3ac5f8ca0465
  • Loading branch information
achembarpu committed Oct 25, 2022
1 parent 4d90e41 commit be64fcc
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 12 deletions.
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ If you change the schema in Bigquery, Argon's schema check will fail.
"projectId": "[BIGQUERY_PROJECT]", // default: current cloud project
"single": [SINGLE_FILE_MODE], // default: true
"ignore": [IGNORE_FILE_IDS], // default: []
"replace": [REPLACE_TABLE_MODE], // default: false, append only
"email": "[EMAIL_ADDRESS]" // default: no impersonation
}
```
Expand All @@ -155,6 +156,9 @@ If you change the schema in Bigquery, Argon's schema check will fail.
- Set `ignore` to a list of Report File IDs, to skip wrongly generated
or unnecessary report files.

- Set `replace` to true, to replace the BigQuery table on running,
instead of appending to it.

- Set `email` to a Service Account email address, to impersonate it
for local development or testing purposes.

Expand Down Expand Up @@ -275,7 +279,7 @@ npm run format

#### Docker

Argon can be containerised using [Pack](https://buildpacks.io/docs/tools/pack).
Argon can be containerized using [Pack](https://buildpacks.io/docs/tools/pack).

```sh
# Build & Run a Docker image, from your local source
Expand Down
17 changes: 16 additions & 1 deletion src/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,10 @@ function isSupportedProduct(product: string): product is SupportedProduct {
return product === 'CM' || product === 'DV';
}

type DefaultArgonOpts = Pick<ArgonOpts, 'projectId' | 'single' | 'ignore'>;
type DefaultArgonOpts = Pick<
ArgonOpts,
'projectId' | 'single' | 'ignore' | 'replace'
>;

/**
* Get a partially filled ArgonOpts with sane defaults.
Expand All @@ -132,6 +135,7 @@ async function getDefaultArgonOpts(): Promise<DefaultArgonOpts> {
projectId: await getProjectId(),
single: true,
ignore: [],
replace: false,
};
}

Expand Down Expand Up @@ -230,6 +234,16 @@ export async function parseBody(body: ParsedJSON): Promise<ArgonOpts> {
warn(`Ignoring file IDs: ${[...ignore]}`);
}

let replace: ArgonOpts['replace'] = defaults.replace;
if ('replace' in body) {
replace = Boolean(body.replace);
}
if (replace) {
warn('Insertion Mode: replace');
} else {
info('Insertion Mode: append');
}

let email: ArgonOpts['email'];
if (
'email' in body &&
Expand All @@ -251,6 +265,7 @@ export async function parseBody(body: ParsedJSON): Promise<ArgonOpts> {
projectId,
single,
ignore,
replace,
email,
};
}
25 changes: 15 additions & 10 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,29 +119,34 @@ export const argon: HttpFunction = async (req, res) => {
const tableName = buildValidBQName(reportName);
info(`Checking for existence of Table ${tableName}.`);
const table = dataset.table(tableName);
const [tableExists] = await table.exists();
let tableSchema;
let [tableExists] = await table.exists();
let tableSchema = null;
if (tableExists) {
info('Fetching BQ table schema for verification.');
const [metadata] = await table.getMetadata();
tableSchema = metadata.schema;
info(`BigQuery table fields: ${getNames(tableSchema)}`);
if (opts.replace) {
warn('Deleting existing Table for replacement.');
await table.delete();
tableExists = false;
} else {
info('Fetching existing Table Schema for verification.');
const [metadata] = await table.getMetadata();
tableSchema = metadata.schema;
info(`BigQuery Table fields: ${getNames(tableSchema)}`);
}
} else {
tableSchema = null;
warn('Table does not already exist.');
info('Table does not exist.');
}

info('Checking ingested files.');
const ignoredIds = new Set(opts.ignore);
const ingestedIds = new Set<number>();
if (tableExists) {
info('Checking ingested files in BigQuery.');
const path = `${opts.projectId}.${opts.datasetName}.${tableName}`;
const query = buildLookbackQuery(path);
const [rows] = await bq.query(query);
rows.forEach(row => ingestedIds.add(Number(row[FILE_ID_COLUMN])));
}

info('Enumerating report files.');
info('Fetching report files from API.');
const reports = await reportFetcher.getReports();
if (reports.size === 0) {
throw Error('No report files found.');
Expand Down
1 change: 1 addition & 0 deletions src/typings.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ export interface ArgonOpts {
projectId: string;
single: boolean;
ignore: number[];
replace: boolean;
email: string | null;
}

Expand Down

0 comments on commit be64fcc

Please sign in to comment.