@bonnard/cli 0.2.2 → 0.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/bon.mjs +8 -125
- package/dist/bin/{cubes-Bf0IPYd7.mjs → cubes-9rklhdAJ.mjs} +1 -1
- package/dist/bin/push-mZujN1Ik.mjs +35 -0
- package/dist/bin/{validate-DEh1XQnH.mjs → validate-BdqZBH2n.mjs} +1 -1
- package/dist/docs/topics/workflow.deploy.md +1 -1
- package/dist/docs/topics/workflow.md +0 -1
- package/dist/docs/topics/workflow.validate.md +1 -1
- package/dist/templates/claude/skills/bonnard-get-started/SKILL.md +13 -15
- package/dist/templates/claude/skills/bonnard-metabase-migrate/SKILL.md +13 -11
- package/dist/templates/cursor/rules/bonnard-get-started.mdc +13 -15
- package/dist/templates/cursor/rules/bonnard-metabase-migrate.mdc +13 -11
- package/dist/templates/shared/bonnard.md +0 -1
- package/package.json +1 -1
package/dist/bin/bon.mjs
CHANGED
|
@@ -1490,7 +1490,7 @@ async function addManual(options) {
|
|
|
1490
1490
|
console.log();
|
|
1491
1491
|
console.log(pc.green(`✓ Datasource "${name}" saved to .bon/datasources.yaml`));
|
|
1492
1492
|
console.log();
|
|
1493
|
-
console.log(pc.dim(`
|
|
1493
|
+
console.log(pc.dim(`Connection will be tested during \`bon deploy\``));
|
|
1494
1494
|
}
|
|
1495
1495
|
/**
|
|
1496
1496
|
* Add the Contoso demo datasource (read-only retail dataset)
|
|
@@ -1523,7 +1523,7 @@ async function addDemo(options) {
|
|
|
1523
1523
|
console.log(pc.dim("Contoso is a read-only retail dataset with tables like:"));
|
|
1524
1524
|
console.log(pc.dim(" fact_sales, dim_product, dim_store, dim_customer"));
|
|
1525
1525
|
console.log();
|
|
1526
|
-
console.log(pc.dim(`
|
|
1526
|
+
console.log(pc.dim(`Connection will be tested during \`bon deploy\``));
|
|
1527
1527
|
}
|
|
1528
1528
|
/**
|
|
1529
1529
|
* Main datasource add command
|
|
@@ -1630,34 +1630,6 @@ async function datasourceListCommand(options = {}) {
|
|
|
1630
1630
|
if (showRemote) await listRemoteDatasources();
|
|
1631
1631
|
}
|
|
1632
1632
|
|
|
1633
|
-
//#endregion
|
|
1634
|
-
//#region src/commands/datasource/test.ts
|
|
1635
|
-
async function datasourceTestCommand(name) {
|
|
1636
|
-
if (!loadCredentials()) {
|
|
1637
|
-
console.log(pc.red("Not logged in. Run `bon login` to test datasources."));
|
|
1638
|
-
process.exit(1);
|
|
1639
|
-
}
|
|
1640
|
-
console.log(pc.dim(`Testing ${name} via remote API...`));
|
|
1641
|
-
console.log();
|
|
1642
|
-
try {
|
|
1643
|
-
const result = await post("/api/datasources/test", { name });
|
|
1644
|
-
if (result.success) {
|
|
1645
|
-
console.log(pc.green(result.message));
|
|
1646
|
-
if (result.details) {
|
|
1647
|
-
if (result.details.warehouse) console.log(pc.dim(` Warehouse: ${result.details.warehouse}`));
|
|
1648
|
-
if (result.details.account) console.log(pc.dim(` Account: ${result.details.account}`));
|
|
1649
|
-
if (result.details.latencyMs != null) console.log(pc.dim(` Latency: ${result.details.latencyMs}ms`));
|
|
1650
|
-
}
|
|
1651
|
-
} else {
|
|
1652
|
-
console.log(pc.red(result.message));
|
|
1653
|
-
process.exit(1);
|
|
1654
|
-
}
|
|
1655
|
-
} catch (err) {
|
|
1656
|
-
console.error(pc.red(`Failed to test data source: ${err.message}`));
|
|
1657
|
-
process.exit(1);
|
|
1658
|
-
}
|
|
1659
|
-
}
|
|
1660
|
-
|
|
1661
1633
|
//#endregion
|
|
1662
1634
|
//#region src/commands/datasource/remove.ts
|
|
1663
1635
|
async function datasourceRemoveCommand(name, options = {}) {
|
|
@@ -1692,93 +1664,6 @@ async function removeRemote(name) {
|
|
|
1692
1664
|
}
|
|
1693
1665
|
}
|
|
1694
1666
|
|
|
1695
|
-
//#endregion
|
|
1696
|
-
//#region src/commands/datasource/push.ts
|
|
1697
|
-
var push_exports = /* @__PURE__ */ __exportAll({
|
|
1698
|
-
datasourcePushCommand: () => datasourcePushCommand,
|
|
1699
|
-
pushDatasource: () => pushDatasource
|
|
1700
|
-
});
|
|
1701
|
-
/**
|
|
1702
|
-
* Push a local datasource to Bonnard server
|
|
1703
|
-
*/
|
|
1704
|
-
async function datasourcePushCommand(name, options = {}) {
|
|
1705
|
-
if (!loadCredentials()) {
|
|
1706
|
-
console.error(pc.red("Not logged in. Run `bon login` first."));
|
|
1707
|
-
process.exit(1);
|
|
1708
|
-
}
|
|
1709
|
-
const datasource = getLocalDatasource(name);
|
|
1710
|
-
if (!datasource) {
|
|
1711
|
-
console.error(pc.red(`Datasource "${name}" not found in .bon/datasources.yaml`));
|
|
1712
|
-
console.log(pc.dim("Run `bon datasource list --local` to see available datasources."));
|
|
1713
|
-
process.exit(1);
|
|
1714
|
-
}
|
|
1715
|
-
const { resolved, missing } = resolveEnvVarsInCredentials(datasource.credentials);
|
|
1716
|
-
if (missing.length > 0) {
|
|
1717
|
-
console.error(pc.red(`Missing environment variables: ${missing.join(", ")}`));
|
|
1718
|
-
console.log(pc.dim("Set them in your environment or use plain values in .bon/datasources.yaml"));
|
|
1719
|
-
process.exit(1);
|
|
1720
|
-
}
|
|
1721
|
-
try {
|
|
1722
|
-
if ((await getRemoteDatasources()).some((ds) => ds.name === name) && !options.force) {
|
|
1723
|
-
if (!await confirm({
|
|
1724
|
-
message: `Datasource "${name}" already exists on remote. Overwrite?`,
|
|
1725
|
-
default: false
|
|
1726
|
-
})) {
|
|
1727
|
-
console.log(pc.dim("Aborted."));
|
|
1728
|
-
process.exit(0);
|
|
1729
|
-
}
|
|
1730
|
-
}
|
|
1731
|
-
} catch (err) {
|
|
1732
|
-
console.log(pc.dim(`Note: Could not check remote datasources: ${err.message}`));
|
|
1733
|
-
}
|
|
1734
|
-
console.log(pc.dim(`Pushing "${name}"...`));
|
|
1735
|
-
try {
|
|
1736
|
-
await post("/api/datasources", {
|
|
1737
|
-
name: datasource.name,
|
|
1738
|
-
warehouse_type: datasource.type,
|
|
1739
|
-
config: datasource.config,
|
|
1740
|
-
credentials: resolved
|
|
1741
|
-
});
|
|
1742
|
-
console.log(pc.green(`✓ Datasource "${name}" pushed to Bonnard`));
|
|
1743
|
-
} catch (err) {
|
|
1744
|
-
const message = err.message;
|
|
1745
|
-
if (message.includes("already exists")) {
|
|
1746
|
-
console.error(pc.red(`Datasource "${name}" already exists on remote.`));
|
|
1747
|
-
console.log(pc.dim("Use --force to overwrite."));
|
|
1748
|
-
process.exit(1);
|
|
1749
|
-
}
|
|
1750
|
-
console.error(pc.red(`Failed to push datasource: ${message}`));
|
|
1751
|
-
process.exit(1);
|
|
1752
|
-
}
|
|
1753
|
-
}
|
|
1754
|
-
/**
|
|
1755
|
-
* Push a datasource programmatically (for use by deploy command)
|
|
1756
|
-
* Returns true on success, false on failure
|
|
1757
|
-
*/
|
|
1758
|
-
async function pushDatasource(name, options = {}) {
|
|
1759
|
-
const datasource = getLocalDatasource(name);
|
|
1760
|
-
if (!datasource) {
|
|
1761
|
-
if (!options.silent) console.error(pc.red(`Datasource "${name}" not found locally`));
|
|
1762
|
-
return false;
|
|
1763
|
-
}
|
|
1764
|
-
const { resolved, missing } = resolveEnvVarsInCredentials(datasource.credentials);
|
|
1765
|
-
if (missing.length > 0) {
|
|
1766
|
-
if (!options.silent) console.error(pc.red(`Missing env vars for "${name}": ${missing.join(", ")}`));
|
|
1767
|
-
return false;
|
|
1768
|
-
}
|
|
1769
|
-
try {
|
|
1770
|
-
await post("/api/datasources", {
|
|
1771
|
-
name: datasource.name,
|
|
1772
|
-
warehouse_type: datasource.type,
|
|
1773
|
-
config: datasource.config,
|
|
1774
|
-
credentials: resolved
|
|
1775
|
-
});
|
|
1776
|
-
return true;
|
|
1777
|
-
} catch {
|
|
1778
|
-
return false;
|
|
1779
|
-
}
|
|
1780
|
-
}
|
|
1781
|
-
|
|
1782
1667
|
//#endregion
|
|
1783
1668
|
//#region src/commands/validate.ts
|
|
1784
1669
|
async function validateCommand() {
|
|
@@ -1788,7 +1673,7 @@ async function validateCommand() {
|
|
|
1788
1673
|
console.log(pc.red("No bon.yaml found. Are you in a Bonnard project?"));
|
|
1789
1674
|
process.exit(1);
|
|
1790
1675
|
}
|
|
1791
|
-
const { validate } = await import("./validate-
|
|
1676
|
+
const { validate } = await import("./validate-BdqZBH2n.mjs");
|
|
1792
1677
|
const result = await validate(cwd);
|
|
1793
1678
|
if (result.cubes.length === 0 && result.views.length === 0 && result.valid) {
|
|
1794
1679
|
console.log(pc.yellow(`No cube or view files found in ${BONNARD_DIR}/cubes/ or ${BONNARD_DIR}/views/.`));
|
|
@@ -1854,7 +1739,7 @@ async function deployCommand(options = {}) {
|
|
|
1854
1739
|
process.exit(1);
|
|
1855
1740
|
}
|
|
1856
1741
|
console.log(pc.dim("Validating cubes and views..."));
|
|
1857
|
-
const { validate } = await import("./validate-
|
|
1742
|
+
const { validate } = await import("./validate-BdqZBH2n.mjs");
|
|
1858
1743
|
const result = await validate(cwd);
|
|
1859
1744
|
if (!result.valid) {
|
|
1860
1745
|
console.log(pc.red("Validation failed:\n"));
|
|
@@ -1923,9 +1808,9 @@ async function deployCommand(options = {}) {
|
|
|
1923
1808
|
* Returns true if any connection failed (strict mode)
|
|
1924
1809
|
*/
|
|
1925
1810
|
async function testAndSyncDatasources(cwd, options = {}) {
|
|
1926
|
-
const { extractDatasourcesFromCubes } = await import("./cubes-
|
|
1811
|
+
const { extractDatasourcesFromCubes } = await import("./cubes-9rklhdAJ.mjs");
|
|
1927
1812
|
const { loadLocalDatasources } = await Promise.resolve().then(() => local_exports);
|
|
1928
|
-
const { pushDatasource } = await
|
|
1813
|
+
const { pushDatasource } = await import("./push-mZujN1Ik.mjs");
|
|
1929
1814
|
const references = extractDatasourcesFromCubes(cwd);
|
|
1930
1815
|
if (references.length === 0) return false;
|
|
1931
1816
|
console.log();
|
|
@@ -1964,7 +1849,7 @@ async function testAndSyncDatasources(cwd, options = {}) {
|
|
|
1964
1849
|
console.log();
|
|
1965
1850
|
if (options.ci) {
|
|
1966
1851
|
console.log(pc.red("Deploy aborted (--ci mode)."));
|
|
1967
|
-
console.log(pc.dim(`
|
|
1852
|
+
console.log(pc.dim(`Use --push-datasources to auto-push missing datasources`));
|
|
1968
1853
|
return true;
|
|
1969
1854
|
}
|
|
1970
1855
|
if (options.pushDatasources) for (const name of missingRemote) {
|
|
@@ -3931,9 +3816,7 @@ program.command("whoami").description("Show current login status").option("--ver
|
|
|
3931
3816
|
const datasource = program.command("datasource").description("Manage warehouse data source connections");
|
|
3932
3817
|
datasource.command("add").description("Add a data source to .bon/datasources.yaml. Use --name and --type together for non-interactive mode").option("--demo", "Add a read-only demo datasource (Contoso retail dataset) for testing").option("--from-dbt [profile]", "Import from dbt profiles.yml (optionally specify profile/target)").option("--target <target>", "Target name when using --from-dbt").option("--all", "Import all connections from dbt profiles").option("--default-targets", "Import only default targets from dbt profiles (non-interactive)").option("--name <name>", "Datasource name (required for non-interactive mode)").option("--type <type>", "Warehouse type: snowflake, postgres, bigquery, databricks (required for non-interactive mode)").option("--account <account>", "Snowflake account identifier").option("--database <database>", "Database name").option("--schema <schema>", "Schema name").option("--warehouse <warehouse>", "Warehouse name (Snowflake)").option("--role <role>", "Role (Snowflake)").option("--host <host>", "Host (Postgres)").option("--port <port>", "Port (Postgres, default: 5432)").option("--project-id <projectId>", "GCP Project ID (BigQuery)").option("--dataset <dataset>", "Dataset name (BigQuery)").option("--location <location>", "Location (BigQuery)").option("--hostname <hostname>", "Server hostname (Databricks)").option("--http-path <httpPath>", "HTTP path (Databricks)").option("--catalog <catalog>", "Catalog name (Databricks)").option("--user <user>", "Username").option("--password <password>", "Password (use --password-env for env var reference)").option("--token <token>", "Access token (use --token-env for env var reference)").option("--service-account-json <json>", "Service account JSON (BigQuery)").option("--keyfile <path>", "Path to service account key file (BigQuery)").option("--password-env <varName>", "Env var name for password, stores as {{ env_var('NAME') }}").option("--token-env <varName>", "Env var name for token, stores as {{ env_var('NAME') }}").option("--force", "Overwrite existing datasource without prompting").action(datasourceAddCommand);
|
|
3933
3818
|
datasource.command("list").description("List data sources (shows both local and remote by default)").option("--local", "Show only local data sources from .bon/datasources.yaml").option("--remote", "Show only remote data sources from Bonnard server (requires login)").action(datasourceListCommand);
|
|
3934
|
-
datasource.command("test").description("Test data source connectivity via Bonnard API (requires login)").argument("<name>", "Data source name from .bon/datasources.yaml").action(datasourceTestCommand);
|
|
3935
3819
|
datasource.command("remove").description("Remove a data source from .bon/datasources.yaml (local by default)").argument("<name>", "Data source name").option("--remote", "Remove from Bonnard server instead of local (requires login)").action(datasourceRemoveCommand);
|
|
3936
|
-
datasource.command("push").description("Push a local data source to Bonnard server (requires login)").argument("<name>", "Data source name from .bon/datasources.yaml").option("--force", "Overwrite if already exists on remote").action(datasourcePushCommand);
|
|
3937
3820
|
program.command("validate").description("Validate YAML syntax in bonnard/cubes/ and bonnard/views/").action(validateCommand);
|
|
3938
3821
|
program.command("deploy").description("Deploy cubes and views to Bonnard. Requires login, validates, syncs datasources").option("--ci", "Non-interactive mode (fail if missing datasources)").option("--push-datasources", "Auto-push missing datasources without prompting").requiredOption("-m, --message <text>", "Deploy message describing your changes").action(deployCommand);
|
|
3939
3822
|
program.command("deployments").description("List deployment history").option("--all", "Show all deployments (default: last 10)").option("--format <format>", "Output format: table or json", "table").action(deploymentsCommand);
|
|
@@ -3949,4 +3832,4 @@ metabase.command("analyze").description("Analyze Metabase instance and generate
|
|
|
3949
3832
|
program.parse();
|
|
3950
3833
|
|
|
3951
3834
|
//#endregion
|
|
3952
|
-
export { getProjectPaths as t };
|
|
3835
|
+
export { getProjectPaths as i, resolveEnvVarsInCredentials as n, post as r, getLocalDatasource as t };
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { n as resolveEnvVarsInCredentials, r as post, t as getLocalDatasource } from "./bon.mjs";
|
|
2
|
+
import pc from "picocolors";
|
|
3
|
+
import { confirm } from "@inquirer/prompts";
|
|
4
|
+
|
|
5
|
+
//#region src/commands/datasource/push.ts
|
|
6
|
+
/**
|
|
7
|
+
* Push a datasource programmatically (for use by deploy command)
|
|
8
|
+
* Returns true on success, false on failure
|
|
9
|
+
*/
|
|
10
|
+
async function pushDatasource(name, options = {}) {
|
|
11
|
+
const datasource = getLocalDatasource(name);
|
|
12
|
+
if (!datasource) {
|
|
13
|
+
if (!options.silent) console.error(pc.red(`Datasource "${name}" not found locally`));
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
const { resolved, missing } = resolveEnvVarsInCredentials(datasource.credentials);
|
|
17
|
+
if (missing.length > 0) {
|
|
18
|
+
if (!options.silent) console.error(pc.red(`Missing env vars for "${name}": ${missing.join(", ")}`));
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
try {
|
|
22
|
+
await post("/api/datasources", {
|
|
23
|
+
name: datasource.name,
|
|
24
|
+
warehouse_type: datasource.type,
|
|
25
|
+
config: datasource.config,
|
|
26
|
+
credentials: resolved
|
|
27
|
+
});
|
|
28
|
+
return true;
|
|
29
|
+
} catch {
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
//#endregion
|
|
35
|
+
export { pushDatasource };
|
|
@@ -148,7 +148,7 @@ Deploy aborted. Fix validation errors first.
|
|
|
148
148
|
Deploy aborted. Fix connection issues:
|
|
149
149
|
- Check credentials in .bon/datasources.yaml
|
|
150
150
|
- Verify network access to database
|
|
151
|
-
- Run: bon datasource
|
|
151
|
+
- Run: bon datasource add (to reconfigure)
|
|
152
152
|
```
|
|
153
153
|
|
|
154
154
|
### Auth Errors
|
|
@@ -146,7 +146,6 @@ bonnard/cubes/
|
|
|
146
146
|
| `bon datasource add --demo` | Add demo dataset (no warehouse needed) |
|
|
147
147
|
| `bon datasource add --from-dbt` | Import from dbt profiles |
|
|
148
148
|
| `bon datasource list` | List configured sources |
|
|
149
|
-
| `bon datasource test <name>` | Test connection (requires login) |
|
|
150
149
|
| `bon validate` | Check cube and view syntax |
|
|
151
150
|
| `bon deploy -m "message"` | Deploy to Bonnard (message required) |
|
|
152
151
|
| `bon deploy --ci` | Non-interactive deploy |
|
|
@@ -116,7 +116,7 @@ measures:
|
|
|
116
116
|
1. **Run before every deploy** — `bon validate && bon deploy`
|
|
117
117
|
2. **Add to CI/CD** — validate on pull requests
|
|
118
118
|
3. **Fix errors first** — don't deploy with validation errors
|
|
119
|
-
4. **Test connections** —
|
|
119
|
+
4. **Test connections** — connections are tested automatically during `bon deploy`
|
|
120
120
|
|
|
121
121
|
## See Also
|
|
122
122
|
|
|
@@ -15,29 +15,27 @@ confirming progress before moving on.
|
|
|
15
15
|
Ask the user if they have a warehouse to connect, or want to try a demo dataset first:
|
|
16
16
|
|
|
17
17
|
```bash
|
|
18
|
-
# Option A:
|
|
18
|
+
# Option A: Use demo data (no warehouse needed)
|
|
19
|
+
bon datasource add --demo
|
|
20
|
+
|
|
21
|
+
# Option B: Import from dbt (if they use it)
|
|
19
22
|
bon datasource add --from-dbt
|
|
20
23
|
|
|
21
|
-
# Option
|
|
22
|
-
bon datasource add
|
|
24
|
+
# Option C: Add manually, non-interactive (preferred for agents)
|
|
25
|
+
bon datasource add --name my_warehouse --type postgres \
|
|
26
|
+
--host db.example.com --port 5432 --database mydb --schema public \
|
|
27
|
+
--user myuser --password mypassword
|
|
23
28
|
|
|
24
|
-
# Option
|
|
25
|
-
bon datasource add
|
|
29
|
+
# Option D: Add manually, interactive (in user's terminal)
|
|
30
|
+
bon datasource add
|
|
26
31
|
```
|
|
27
32
|
|
|
33
|
+
Supported types: `postgres` (also works for Redshift), `snowflake`, `bigquery`, `databricks`.
|
|
34
|
+
|
|
28
35
|
The demo option adds a read-only Contoso retail dataset with tables like
|
|
29
36
|
`fact_sales`, `dim_product`, `dim_store`, and `dim_customer`.
|
|
30
37
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
```bash
|
|
34
|
-
bon datasource test <name>
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
If the test fails, common issues:
|
|
38
|
-
- Wrong credentials — re-run `bon datasource add`
|
|
39
|
-
- Network/firewall — check warehouse allows connections from this machine
|
|
40
|
-
- SSL issues (Postgres) — may need `sslmode` in connection config
|
|
38
|
+
The connection will be tested automatically during `bon deploy`.
|
|
41
39
|
|
|
42
40
|
## Phase 2: Explore the Data
|
|
43
41
|
|
|
@@ -48,24 +48,26 @@ drives every decision in the remaining phases.
|
|
|
48
48
|
|
|
49
49
|
## Phase 3: Connect the Data Warehouse
|
|
50
50
|
|
|
51
|
-
Add a datasource pointing to the same database that Metabase queries
|
|
51
|
+
Add a datasource pointing to the same database that Metabase queries.
|
|
52
|
+
The database connection details can often be found in Metabase under
|
|
53
|
+
Admin > Databases, or in the analysis report header.
|
|
52
54
|
|
|
53
55
|
```bash
|
|
54
|
-
#
|
|
55
|
-
bon datasource add
|
|
56
|
+
# Non-interactive (preferred for agents)
|
|
57
|
+
bon datasource add --name my_warehouse --type postgres \
|
|
58
|
+
--host db.example.com --port 5432 --database mydb --schema public \
|
|
59
|
+
--user myuser --password mypassword
|
|
56
60
|
|
|
57
|
-
#
|
|
61
|
+
# Import from dbt if available
|
|
58
62
|
bon datasource add --from-dbt
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
Then verify the connection:
|
|
62
63
|
|
|
63
|
-
|
|
64
|
-
bon datasource
|
|
64
|
+
# Interactive setup (in user's terminal)
|
|
65
|
+
bon datasource add
|
|
65
66
|
```
|
|
66
67
|
|
|
67
|
-
|
|
68
|
-
|
|
68
|
+
Supported types: `postgres` (also works for Redshift), `snowflake`, `bigquery`, `databricks`.
|
|
69
|
+
|
|
70
|
+
The connection will be tested automatically during `bon deploy`.
|
|
69
71
|
|
|
70
72
|
## Phase 4: Explore Key Tables
|
|
71
73
|
|
|
@@ -14,29 +14,27 @@ confirming progress before moving on.
|
|
|
14
14
|
Ask the user if they have a warehouse to connect, or want to try a demo dataset first:
|
|
15
15
|
|
|
16
16
|
```bash
|
|
17
|
-
# Option A:
|
|
17
|
+
# Option A: Use demo data (no warehouse needed)
|
|
18
|
+
bon datasource add --demo
|
|
19
|
+
|
|
20
|
+
# Option B: Import from dbt (if they use it)
|
|
18
21
|
bon datasource add --from-dbt
|
|
19
22
|
|
|
20
|
-
# Option
|
|
21
|
-
bon datasource add
|
|
23
|
+
# Option C: Add manually, non-interactive (preferred for agents)
|
|
24
|
+
bon datasource add --name my_warehouse --type postgres \
|
|
25
|
+
--host db.example.com --port 5432 --database mydb --schema public \
|
|
26
|
+
--user myuser --password mypassword
|
|
22
27
|
|
|
23
|
-
# Option
|
|
24
|
-
bon datasource add
|
|
28
|
+
# Option D: Add manually, interactive (in user's terminal)
|
|
29
|
+
bon datasource add
|
|
25
30
|
```
|
|
26
31
|
|
|
32
|
+
Supported types: `postgres` (also works for Redshift), `snowflake`, `bigquery`, `databricks`.
|
|
33
|
+
|
|
27
34
|
The demo option adds a read-only Contoso retail dataset with tables like
|
|
28
35
|
`fact_sales`, `dim_product`, `dim_store`, and `dim_customer`.
|
|
29
36
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
```bash
|
|
33
|
-
bon datasource test <name>
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
If the test fails, common issues:
|
|
37
|
-
- Wrong credentials — re-run `bon datasource add`
|
|
38
|
-
- Network/firewall — check warehouse allows connections from this machine
|
|
39
|
-
- SSL issues (Postgres) — may need `sslmode` in connection config
|
|
37
|
+
The connection will be tested automatically during `bon deploy`.
|
|
40
38
|
|
|
41
39
|
## Phase 2: Explore the Data
|
|
42
40
|
|
|
@@ -47,24 +47,26 @@ drives every decision in the remaining phases.
|
|
|
47
47
|
|
|
48
48
|
## Phase 3: Connect the Data Warehouse
|
|
49
49
|
|
|
50
|
-
Add a datasource pointing to the same database that Metabase queries
|
|
50
|
+
Add a datasource pointing to the same database that Metabase queries.
|
|
51
|
+
The database connection details can often be found in Metabase under
|
|
52
|
+
Admin > Databases, or in the analysis report header.
|
|
51
53
|
|
|
52
54
|
```bash
|
|
53
|
-
#
|
|
54
|
-
bon datasource add
|
|
55
|
+
# Non-interactive (preferred for agents)
|
|
56
|
+
bon datasource add --name my_warehouse --type postgres \
|
|
57
|
+
--host db.example.com --port 5432 --database mydb --schema public \
|
|
58
|
+
--user myuser --password mypassword
|
|
55
59
|
|
|
56
|
-
#
|
|
60
|
+
# Import from dbt if available
|
|
57
61
|
bon datasource add --from-dbt
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
Then verify the connection:
|
|
61
62
|
|
|
62
|
-
|
|
63
|
-
bon datasource
|
|
63
|
+
# Interactive setup (in user's terminal)
|
|
64
|
+
bon datasource add
|
|
64
65
|
```
|
|
65
66
|
|
|
66
|
-
|
|
67
|
-
|
|
67
|
+
Supported types: `postgres` (also works for Redshift), `snowflake`, `bigquery`, `databricks`.
|
|
68
|
+
|
|
69
|
+
The connection will be tested automatically during `bon deploy`.
|
|
68
70
|
|
|
69
71
|
## Phase 4: Explore Key Tables
|
|
70
72
|
|
|
@@ -63,7 +63,6 @@ All tables are in the `contoso` schema. The datasource is named `contoso_demo`.
|
|
|
63
63
|
| `bon datasource add` | Add warehouse connection |
|
|
64
64
|
| `bon datasource add --demo` | Add demo dataset (no warehouse needed) |
|
|
65
65
|
| `bon datasource add --from-dbt` | Import from dbt profiles |
|
|
66
|
-
| `bon datasource test <name>` | Test connection (requires login) |
|
|
67
66
|
| `bon validate` | Validate YAML syntax, warn on missing descriptions and `data_source` |
|
|
68
67
|
| `bon deploy -m "message"` | Deploy to Bonnard (requires login, message required) |
|
|
69
68
|
| `bon deploy --ci` | Non-interactive deploy (fails on missing datasources) |
|