mammoth-cli 2.2.31__tar.gz → 2.2.33__tar.gz
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.
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/PKG-INFO +1 -1
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/__init__.py +1 -1
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/bundled_skill/mammoth-cli/references/about-mammoth.md +6 -1
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/exports.md +5 -1
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/commands/batch.py +26 -4
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/commands/view.py +92 -33
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/errors/envelope.py +3 -0
- mammoth_cli-2.2.33/mammoth_cli/services/append_blank_columns.py +57 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/services/command_contract.py +8 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/pyproject.toml +1 -1
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/spec/manifests/commands/batch.yaml +1 -1
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/spec/manifests/commands/view.yaml +2 -2
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/.gitignore +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/LICENSE +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/README.md +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/__main__.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/app.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/bundled_skill/mammoth-cli/SKILL.md +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/bundled_skill/mammoth-cli/references/auth.md +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/bundled_skill/mammoth-cli/references/capabilities-misc.md +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/bundled_skill/mammoth-cli/references/capabilities.md +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/bundled_skill/mammoth-cli/references/command-index.md +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/activity.md +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/addon.md +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/agent.md +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/ai.md +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/annotation.md +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/auth.md +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/automation.md +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/batch.md +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/billing.md +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/browse.md +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/calc.md +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/capability.md +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/client-app.md +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/completion.md +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/config.md +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/connector.md +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/context.md +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/dashboard-qa.md +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/dashboard-style.md +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/dashboard-template.md +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/dashboard.md +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/data-app.md +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/dataset.md +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/doctor.md +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/external-key.md +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/file.md +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/folder.md +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/job.md +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/link.md +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/log.md +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/notification.md +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/parameter.md +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/project.md +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/report.md +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/schedule.md +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/schema.md +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/skill.md +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/snippet.md +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/support.md +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/template.md +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/trash.md +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/upgrade.md +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/user.md +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/version.md +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/view-transform.md +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/view.md +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/webhook.md +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/workflow.md +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/bundled_skill/mammoth-cli/references/commands/workspace.md +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/bundled_skill/mammoth-cli/references/handoff.md +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/bundled_skill/mammoth-cli/references/input.md +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/bundled_skill/mammoth-cli/references/jobs-drafts.md +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/bundled_skill/mammoth-cli/references/machine-output.md +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/bundled_skill/mammoth-cli/references/operations.md +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/auth-scope.md +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/cleanup.md +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/dashboards.md +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/database-import.md +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/end-to-end.md +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/index.md +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/need-action.md +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/resources.md +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/scheduling.md +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/transforms.md +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/bundled_skill/mammoth-cli/references/recipes/typed-etl-discovery.md +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/bundled_skill/mammoth-cli/references/recovery.md +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/bundled_skill/mammoth-cli/references/report-checklist.md +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/bundled_skill/mammoth-cli/references/retention.md +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/bundled_skill/mammoth-cli/references/safety.md +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/bundled_skill/mammoth-cli/references/task-start.md +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/commands/__init__.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/commands/activity.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/commands/addon.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/commands/agent.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/commands/ai.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/commands/annotation.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/commands/auth.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/commands/automation.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/commands/billing.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/commands/browse.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/commands/calc.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/commands/capability.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/commands/client_app.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/commands/completion.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/commands/config.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/commands/connector.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/commands/context.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/commands/dashboard.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/commands/data_app.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/commands/dataset.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/commands/doctor.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/commands/external_key.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/commands/file.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/commands/folder.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/commands/job.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/commands/link.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/commands/notification.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/commands/parameter.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/commands/project.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/commands/registry.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/commands/report.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/commands/schedule.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/commands/schema.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/commands/skill.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/commands/snippet.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/commands/support.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/commands/template.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/commands/trash.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/commands/upgrade.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/commands/user.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/commands/view_ops.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/commands/view_profile.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/commands/webhook.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/commands/workflow.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/commands/workspace.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/context/__init__.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/context/credentials.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/context/endpoint.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/context/profiles.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/context/resolver.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/contracts/__init__.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/contracts/auth.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/embed.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/errors/__init__.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/manifest/__init__.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/manifest/loader.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/messages/__init__.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/output/__init__.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/output/envelope.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/output/normalize.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/output/policy.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/output/progress.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/output/render.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/py.typed +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/runtime/__init__.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/runtime/confirm.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/runtime/dataset_health.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/runtime/dryrun.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/runtime/dryrun_targets.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/runtime/embedded.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/runtime/executor.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/runtime/input_loader.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/runtime/intent_only.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/runtime/invocation.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/runtime/new_data.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/runtime/options.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/runtime/parents.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/runtime/runlog.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/runtime/session.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/runtime/state.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/runtime/strict.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/runtime/updates.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/runtime/validate.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/runtime/verify.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/services/__init__.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/services/argspec.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/services/board_values.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/services/coerce.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/services/conditional_format.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/services/conditions.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/services/dashboard_filters.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/services/dashboard_pages.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/services/dashboard_review.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/services/data_profile.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/services/data_quality.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/services/dispatch.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/services/factory.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/services/input_fields.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/services/listing.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/services/local_time.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/services/mapping.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/services/openapi_types.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/services/positionals.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/services/protocol.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/services/read_queries.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/services/sdk_service.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/services/sql_check.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/services/stored_stats.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/services/testing.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/services/text_dates.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/services/type_system.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/services/write_impact.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/skills/__init__.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/skills/installer.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/skills/steering.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/testing.py +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/spec/manifests/commands/activity.yaml +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/spec/manifests/commands/addon.yaml +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/spec/manifests/commands/agent.yaml +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/spec/manifests/commands/ai.yaml +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/spec/manifests/commands/annotation.yaml +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/spec/manifests/commands/auth.yaml +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/spec/manifests/commands/automation.yaml +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/spec/manifests/commands/billing.yaml +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/spec/manifests/commands/browse.yaml +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/spec/manifests/commands/calc.yaml +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/spec/manifests/commands/capability.yaml +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/spec/manifests/commands/client-app.yaml +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/spec/manifests/commands/completion.yaml +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/spec/manifests/commands/config.yaml +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/spec/manifests/commands/connector.yaml +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/spec/manifests/commands/context.yaml +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/spec/manifests/commands/dashboard.yaml +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/spec/manifests/commands/data-app.yaml +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/spec/manifests/commands/dataset.yaml +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/spec/manifests/commands/doctor.yaml +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/spec/manifests/commands/external-key.yaml +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/spec/manifests/commands/file.yaml +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/spec/manifests/commands/folder.yaml +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/spec/manifests/commands/job.yaml +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/spec/manifests/commands/link.yaml +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/spec/manifests/commands/log.yaml +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/spec/manifests/commands/notification.yaml +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/spec/manifests/commands/parameter.yaml +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/spec/manifests/commands/project.yaml +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/spec/manifests/commands/report.yaml +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/spec/manifests/commands/schedule.yaml +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/spec/manifests/commands/schema.yaml +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/spec/manifests/commands/skill.yaml +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/spec/manifests/commands/snippet.yaml +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/spec/manifests/commands/support.yaml +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/spec/manifests/commands/template.yaml +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/spec/manifests/commands/trash.yaml +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/spec/manifests/commands/upgrade.yaml +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/spec/manifests/commands/user.yaml +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/spec/manifests/commands/version.yaml +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/spec/manifests/commands/webhook.yaml +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/spec/manifests/commands/workflow.yaml +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/spec/manifests/commands/workspace.yaml +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/spec/manifests/edits-target.source.yaml +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/spec/manifests/openapi-operations.yaml +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/spec/manifests/schema-v1.json +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/spec/manifests/sdk-catalog.source.yaml +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/spec/manifests/sdk-methods.yaml +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/spec/openapi/metadata.json +0 -0
- {mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/spec/openapi/openapi.json +0 -0
|
@@ -146,7 +146,12 @@ No command:
|
|
|
146
146
|
every source column to an existing target column. A partial mapping, or a
|
|
147
147
|
destination the target lacks, is refused with `append_mapping_incomplete`
|
|
148
148
|
before anything is written (the backend would append only the mapped columns
|
|
149
|
-
and add a new column for the unknown name).
|
|
149
|
+
and add a new column for the unknown name). A target column the append
|
|
150
|
+
leaves unfilled would be NULL in every appended row: it is refused with
|
|
151
|
+
`append_leaves_columns_blank` unless the input names exactly those columns,
|
|
152
|
+
e.g. `"blank_columns": ["id","score"]` (a deliberate partial append, such as
|
|
153
|
+
mapping only `name`); never delete source columns or clone the source view to
|
|
154
|
+
get around it. An append is a standing link: it is stored
|
|
150
155
|
as a pipeline step of the source view, so every later re-run of that view
|
|
151
156
|
appends again into the target dataset, not just the first run. A column
|
|
152
157
|
with the same name but a different type in the source view and the target
|
|
@@ -55,7 +55,11 @@ there is no separate Auto-Sync endpoint or field to find.
|
|
|
55
55
|
`target_ds_id` writes into an existing dataset instead of creating one
|
|
56
56
|
(`save_as_mode` `REPLACE_IN_DS` or `APPEND_TO_DS`). Read the delivery back in
|
|
57
57
|
the target project (`view list N --project P`, `view data get`) before
|
|
58
|
-
reporting it.
|
|
58
|
+
reporting it. An append that leaves target columns unfilled (a partial
|
|
59
|
+
`column_mapping`, or a source with fewer columns) is refused with
|
|
60
|
+
`append_leaves_columns_blank` unless the input lists exactly those columns,
|
|
61
|
+
`"blank_columns": ["id","score"]`; confirm that with the user, and never
|
|
62
|
+
clone the source view or delete its columns to get around the refusal. Do not build this with `view export create`: the raw
|
|
59
63
|
`internal_dataset` spec needs `USER_ID` and the `export_project` /
|
|
60
64
|
`project_id` / `source_project_id` trio, and without them the backend answers
|
|
61
65
|
`4GENR007 Validation error` with no detail; the typed command fills them.
|
|
@@ -25,6 +25,10 @@ from mammoth_cli.manifest.loader import command_by_id
|
|
|
25
25
|
from mammoth_cli.runtime.confirm import POLICY_PROMPT_OR_YES, enforce_confirmation
|
|
26
26
|
from mammoth_cli.runtime.invocation import Invocation
|
|
27
27
|
from mammoth_cli.runtime.session import open_service, require_project
|
|
28
|
+
from mammoth_cli.services.append_blank_columns import (
|
|
29
|
+
BLANK_COLUMNS_FIELD,
|
|
30
|
+
acknowledged_blank_columns,
|
|
31
|
+
)
|
|
28
32
|
|
|
29
33
|
HandlerResult = tuple[Any, dict[str, Any]]
|
|
30
34
|
|
|
@@ -221,15 +225,32 @@ def _reject_type_change(item: dict[str, Any], dest_col: dict[str, Any], dataset_
|
|
|
221
225
|
)
|
|
222
226
|
|
|
223
227
|
|
|
228
|
+
def _filled_destination_names(
|
|
229
|
+
items: list[dict[str, Any]], dest: list[dict[str, Any]], source: list[dict[str, Any]]
|
|
230
|
+
) -> set[str]:
|
|
231
|
+
"""Destination column names some mapping item fills (``add_column`` items included)."""
|
|
232
|
+
dest_names = {col["c_name"] for col in dest}
|
|
233
|
+
filled: set[str] = set()
|
|
234
|
+
for item in items:
|
|
235
|
+
_, dest_col = _resolve_item(item, source, dest)
|
|
236
|
+
if dest_col is not None:
|
|
237
|
+
filled.add(dest_col["c_name"])
|
|
238
|
+
elif item.get("action") == "add_column" and item.get("destination_c_name") in dest_names:
|
|
239
|
+
filled.add(item["destination_c_name"])
|
|
240
|
+
return filled
|
|
241
|
+
|
|
242
|
+
|
|
224
243
|
def _checked_batch_mapping(
|
|
225
|
-
service: Any, dataset_id: int, source_id: int, mapping: Any
|
|
244
|
+
service: Any, dataset_id: int, source_id: int, mapping: Any, blank_columns: Any = None
|
|
226
245
|
) -> tuple[list[dict[str, Any]], list[str]]:
|
|
227
246
|
"""Validate a batch mapping against both schemas; return typed items and warnings.
|
|
228
247
|
|
|
229
248
|
Refuses unmapped source columns and unknown destinations (the backend appends
|
|
230
249
|
only the mapped columns) and stamps every item with the destination's actual
|
|
231
250
|
current type, so no destination column is silently re-typed. A mapped pair
|
|
232
|
-
whose source and destination types differ is returned as a warning.
|
|
251
|
+
whose source and destination types differ is returned as a warning. A
|
|
252
|
+
destination column no item fills is refused unless ``blank_columns`` names
|
|
253
|
+
exactly those columns; the confirmed blanks are returned as a warning.
|
|
233
254
|
"""
|
|
234
255
|
source = _dataset_columns(service, source_id, "source")
|
|
235
256
|
dest = _dataset_columns(service, dataset_id, "target")
|
|
@@ -258,7 +279,8 @@ def _checked_batch_mapping(
|
|
|
258
279
|
_reject_incomplete_batch_mapping(
|
|
259
280
|
(dataset_id, source_id), {col["c_name"] for col in source}, mapped_sources, unknown
|
|
260
281
|
)
|
|
261
|
-
|
|
282
|
+
blank = sorted({col["c_name"] for col in dest} - _filled_destination_names(typed, dest, source))
|
|
283
|
+
return typed, acknowledged_blank_columns(dataset_id, blank, blank_columns) + warnings
|
|
262
284
|
|
|
263
285
|
|
|
264
286
|
def batch_create(invocation: Invocation) -> HandlerResult:
|
|
@@ -297,7 +319,7 @@ def batch_create(invocation: Invocation) -> HandlerResult:
|
|
|
297
319
|
)
|
|
298
320
|
with open_service(invocation) as (service, auth):
|
|
299
321
|
kwargs["mapping"], warnings = _checked_batch_mapping(
|
|
300
|
-
service, dataset_id, source_id, mapping
|
|
322
|
+
service, dataset_id, source_id, mapping, document.get(BLANK_COLUMNS_FIELD)
|
|
301
323
|
)
|
|
302
324
|
data = service.call(_symbol(invocation), **kwargs)
|
|
303
325
|
if warnings and isinstance(data, dict):
|
|
@@ -55,6 +55,10 @@ from mammoth_cli.runtime.invocation import Invocation
|
|
|
55
55
|
from mammoth_cli.runtime.session import open_service, require_project
|
|
56
56
|
from mammoth_cli.services import conditional_format as cf_rules
|
|
57
57
|
from mammoth_cli.services import read_queries, text_dates
|
|
58
|
+
from mammoth_cli.services.append_blank_columns import (
|
|
59
|
+
BLANK_COLUMNS_FIELD,
|
|
60
|
+
acknowledged_blank_columns,
|
|
61
|
+
)
|
|
58
62
|
from mammoth_cli.services.conditions import CONDITION_KWARG, compile_condition
|
|
59
63
|
from mammoth_cli.services.dashboard_review import UPLOAD_NOTE, upload_hints
|
|
60
64
|
from mammoth_cli.services.data_quality import column_warnings, duplicate_rows_fact
|
|
@@ -2963,8 +2967,16 @@ def view_pipeline_rerun(invocation: Invocation) -> HandlerResult:
|
|
|
2963
2967
|
service, invocation, dataview_id, document, 1
|
|
2964
2968
|
)
|
|
2965
2969
|
before = _rows_before(service, dataset_id, dataview_id, invocation.project)
|
|
2966
|
-
fired = _end_of_pipeline_exports(
|
|
2967
|
-
|
|
2970
|
+
fired = _end_of_pipeline_exports(
|
|
2971
|
+
service, dataview_id, dataset_id, with_blank_columns=invocation.dry_run
|
|
2972
|
+
)
|
|
2973
|
+
try:
|
|
2974
|
+
data = service.call(_symbol(invocation), **kwargs)
|
|
2975
|
+
except DryRunStop as stop:
|
|
2976
|
+
# The dry run's report names the exports the real run would fire, and
|
|
2977
|
+
# the destination columns each append would leave blank.
|
|
2978
|
+
stop.record["exports_fired"] = fired
|
|
2979
|
+
raise
|
|
2968
2980
|
data = _settle_async_view_write(
|
|
2969
2981
|
service, dataset_id, dataview_id, invocation.project, data, before
|
|
2970
2982
|
)
|
|
@@ -2974,17 +2986,29 @@ def view_pipeline_rerun(invocation: Invocation) -> HandlerResult:
|
|
|
2974
2986
|
|
|
2975
2987
|
|
|
2976
2988
|
#: Non-secret ``target_properties`` keys that say where an export writes.
|
|
2977
|
-
_EXPORT_TARGET_HINT_KEYS = (
|
|
2989
|
+
_EXPORT_TARGET_HINT_KEYS = (
|
|
2990
|
+
"table",
|
|
2991
|
+
"host",
|
|
2992
|
+
"database",
|
|
2993
|
+
"TARGET_DS_ID",
|
|
2994
|
+
"DS_NAME",
|
|
2995
|
+
"SAVE_AS_DS_MODE",
|
|
2996
|
+
"emails",
|
|
2997
|
+
)
|
|
2998
|
+
_INTERNAL_DATASET_HANDLER = "internal_dataset"
|
|
2999
|
+
_WRITE_INTO_EXISTING_MODES = ("APPEND_TO_DS", "REPLACE_IN_DS")
|
|
2978
3000
|
|
|
2979
3001
|
|
|
2980
3002
|
def _end_of_pipeline_exports(
|
|
2981
|
-
service: Any, dataview_id: int, dataset_id: int | None
|
|
3003
|
+
service: Any, dataview_id: int, dataset_id: int | None, *, with_blank_columns: bool = False
|
|
2982
3004
|
) -> list[dict[str, Any]]:
|
|
2983
3005
|
"""The live end-of-pipeline exports a rerun of this view fires again.
|
|
2984
3006
|
|
|
2985
3007
|
A rerun re-sends every one of them to its destination (database, email, REST
|
|
2986
3008
|
endpoint, another dataset), so the caller is told which, not just that the
|
|
2987
|
-
pipeline ran. Soft-deleted exports do not fire.
|
|
3009
|
+
pipeline ran. Soft-deleted exports do not fire. ``with_blank_columns`` (dry run
|
|
3010
|
+
only) also reads the schemas to name the destination columns each append would
|
|
3011
|
+
leave blank; a real rerun makes no such reads.
|
|
2988
3012
|
"""
|
|
2989
3013
|
listing = service.call(
|
|
2990
3014
|
_EXPORTS_LIST_SYMBOL,
|
|
@@ -2993,23 +3017,66 @@ def _end_of_pipeline_exports(
|
|
|
2993
3017
|
end_of_pipeline=True,
|
|
2994
3018
|
)
|
|
2995
3019
|
fired: list[dict[str, Any]] = []
|
|
3020
|
+
source_columns: Any = None
|
|
2996
3021
|
for export in getattr(listing, "exports", None) or []:
|
|
2997
3022
|
if export.status is ExportStatus.DELETED:
|
|
2998
3023
|
continue
|
|
2999
|
-
handler = export.handler_type
|
|
3024
|
+
handler = getattr(export.handler_type, "value", export.handler_type)
|
|
3000
3025
|
properties = export.target_properties or {}
|
|
3001
|
-
|
|
3002
|
-
|
|
3003
|
-
|
|
3004
|
-
|
|
3005
|
-
|
|
3006
|
-
|
|
3007
|
-
|
|
3008
|
-
|
|
3009
|
-
|
|
3026
|
+
entry: dict[str, Any] = {
|
|
3027
|
+
"export_id": export.id,
|
|
3028
|
+
"handler_type": handler,
|
|
3029
|
+
"target": {
|
|
3030
|
+
key: properties[key] for key in _EXPORT_TARGET_HINT_KEYS if key in properties
|
|
3031
|
+
},
|
|
3032
|
+
}
|
|
3033
|
+
if with_blank_columns and _writes_into_existing_dataset(handler, properties):
|
|
3034
|
+
if source_columns is None:
|
|
3035
|
+
source_columns = _source_column_names(service, dataview_id, dataset_id)
|
|
3036
|
+
entry[BLANK_COLUMNS_FIELD] = _blank_destination_columns(
|
|
3037
|
+
source_columns,
|
|
3038
|
+
set(_target_dataset_schema(service, int(properties["TARGET_DS_ID"]))),
|
|
3039
|
+
properties.get("COLUMN_MAPPING"),
|
|
3040
|
+
)
|
|
3041
|
+
fired.append(entry)
|
|
3010
3042
|
return fired
|
|
3011
3043
|
|
|
3012
3044
|
|
|
3045
|
+
def _writes_into_existing_dataset(handler: Any, properties: dict[str, Any]) -> bool:
|
|
3046
|
+
"""Whether an export appends or replaces into a dataset that already exists."""
|
|
3047
|
+
return (
|
|
3048
|
+
handler == _INTERNAL_DATASET_HANDLER
|
|
3049
|
+
and properties.get("TARGET_DS_ID") is not None
|
|
3050
|
+
and properties.get("SAVE_AS_DS_MODE") in _WRITE_INTO_EXISTING_MODES
|
|
3051
|
+
)
|
|
3052
|
+
|
|
3053
|
+
|
|
3054
|
+
def _source_column_names(service: Any, dataview_id: int, dataset_id: int | None) -> set[str]:
|
|
3055
|
+
"""The source view's column display names; unreadable is an error, never "none"."""
|
|
3056
|
+
columns = service.call_view(dataview_id, "columns", dataset_id=dataset_id)
|
|
3057
|
+
if not isinstance(columns, dict):
|
|
3058
|
+
raise CliError(
|
|
3059
|
+
code="append_schema_unreadable",
|
|
3060
|
+
message=f"Could not read view {dataview_id}'s columns before the append.",
|
|
3061
|
+
hint="Read the source view before appending from it.",
|
|
3062
|
+
details={"side": "source", "dataview_id": dataview_id},
|
|
3063
|
+
)
|
|
3064
|
+
return set(columns)
|
|
3065
|
+
|
|
3066
|
+
|
|
3067
|
+
def _blank_destination_columns(
|
|
3068
|
+
source_names: set[str], target_names: set[str], column_mapping: Any
|
|
3069
|
+
) -> list[str]:
|
|
3070
|
+
"""The destination columns an append leaves NULL: in the target, fed by nothing.
|
|
3071
|
+
|
|
3072
|
+
That is a target column that is neither a source column (matched by name) nor a
|
|
3073
|
+
``column_mapping`` destination. The one rule behind both the export-create
|
|
3074
|
+
acknowledgement and the rerun report.
|
|
3075
|
+
"""
|
|
3076
|
+
mapping = column_mapping if isinstance(column_mapping, dict) else {}
|
|
3077
|
+
return sorted(target_names - source_names - set(mapping.values()))
|
|
3078
|
+
|
|
3079
|
+
|
|
3013
3080
|
#: Seconds ``view pipeline wait`` waits when the caller names no ``timeout`` (the SDK's own
|
|
3014
3081
|
#: default is an hour, one request every few seconds for as long as it runs).
|
|
3015
3082
|
_PIPELINE_WAIT_TIMEOUT = 300.0
|
|
@@ -3614,6 +3681,8 @@ def view_export_specialized(invocation: Invocation) -> HandlerResult:
|
|
|
3614
3681
|
allowed = explicit_fields | common_fields | {_DATASET_ID_FIELD}
|
|
3615
3682
|
if invocation.command_id in _DB_REPLACE_ROUTES:
|
|
3616
3683
|
allowed = allowed | {_REPLACE_TABLE_FIELD}
|
|
3684
|
+
if invocation.command_id == "view.export.dataset":
|
|
3685
|
+
allowed = allowed | {BLANK_COLUMNS_FIELD}
|
|
3617
3686
|
unknown = sorted(set(document) - allowed)
|
|
3618
3687
|
if unknown:
|
|
3619
3688
|
raise CliError(
|
|
@@ -3647,6 +3716,7 @@ def view_export_specialized(invocation: Invocation) -> HandlerResult:
|
|
|
3647
3716
|
kwargs = dict(document)
|
|
3648
3717
|
kwargs.pop(_DATASET_ID_FIELD, None)
|
|
3649
3718
|
kwargs.pop(_REPLACE_TABLE_FIELD, None)
|
|
3719
|
+
blank_columns = kwargs.pop(BLANK_COLUMNS_FIELD, None)
|
|
3650
3720
|
is_dataset_route = invocation.command_id == "view.export.dataset"
|
|
3651
3721
|
target_ds_id = kwargs.get("target_ds_id") if is_dataset_route else None
|
|
3652
3722
|
save_as_mode = kwargs.get("save_as_mode") if is_dataset_route else None
|
|
@@ -3663,6 +3733,7 @@ def view_export_specialized(invocation: Invocation) -> HandlerResult:
|
|
|
3663
3733
|
int(target_ds_id) if target_ds_id is not None else None,
|
|
3664
3734
|
)
|
|
3665
3735
|
target_view_before = None
|
|
3736
|
+
blank_warnings: list[str] = []
|
|
3666
3737
|
target_only_columns: list[str] = []
|
|
3667
3738
|
mapped_type_warnings: list[str] = []
|
|
3668
3739
|
hidden_left_out = (
|
|
@@ -3684,6 +3755,9 @@ def view_export_specialized(invocation: Invocation) -> HandlerResult:
|
|
|
3684
3755
|
int(target_ds_id),
|
|
3685
3756
|
kwargs.get("column_mapping"),
|
|
3686
3757
|
)
|
|
3758
|
+
blank_warnings = acknowledged_blank_columns(
|
|
3759
|
+
int(target_ds_id), target_only_columns, blank_columns
|
|
3760
|
+
)
|
|
3687
3761
|
try:
|
|
3688
3762
|
data = service.call_view(dataview_id, method, dataset_id=dataset_id, **kwargs)
|
|
3689
3763
|
except CliError as error:
|
|
@@ -3745,14 +3819,7 @@ def view_export_specialized(invocation: Invocation) -> HandlerResult:
|
|
|
3745
3819
|
"hidden column(s) of the source view are not in the new dataset: "
|
|
3746
3820
|
+ ", ".join(hidden_left_out)
|
|
3747
3821
|
)
|
|
3748
|
-
|
|
3749
|
-
# Allowed -- an append never has to cover every target column
|
|
3750
|
-
# -- but worth surfacing rather than leaving silent.
|
|
3751
|
-
warnings.insert(
|
|
3752
|
-
0,
|
|
3753
|
-
"target dataset has column(s) the source view does not (kept "
|
|
3754
|
-
"as-is): " + ", ".join(target_only_columns),
|
|
3755
|
-
)
|
|
3822
|
+
warnings[:0] = blank_warnings
|
|
3756
3823
|
if warnings:
|
|
3757
3824
|
row_check["warnings"] = warnings
|
|
3758
3825
|
data["row_check"] = row_check
|
|
@@ -4073,24 +4140,16 @@ def _reject_append_schema_mismatch(
|
|
|
4073
4140
|
in the source, not a ``column_mapping`` destination) and the type
|
|
4074
4141
|
warnings for mapped pairs -- both allowed, but worth a warning.
|
|
4075
4142
|
"""
|
|
4076
|
-
|
|
4077
|
-
if not isinstance(source_columns, dict):
|
|
4078
|
-
raise CliError(
|
|
4079
|
-
code="append_schema_unreadable",
|
|
4080
|
-
message=f"Could not read view {dataview_id}'s columns before the append.",
|
|
4081
|
-
hint="Read the source view before appending from it.",
|
|
4082
|
-
details={"side": "source", "dataview_id": dataview_id},
|
|
4083
|
-
)
|
|
4143
|
+
source_names = _source_column_names(service, dataview_id, dataset_id)
|
|
4084
4144
|
target_schema = _target_dataset_schema(service, target_ds_id)
|
|
4085
4145
|
target_names = set(target_schema)
|
|
4086
4146
|
mapping = column_mapping if isinstance(column_mapping, dict) else {}
|
|
4087
4147
|
# View.columns (mammoth/view.py) maps display name -> internal name; these
|
|
4088
4148
|
# dict keys are display names, matching what the backend's own schema
|
|
4089
4149
|
# match compares by -- never the internal ids in the dict's values.
|
|
4090
|
-
source_names = set(source_columns)
|
|
4091
4150
|
_reject_partial_append_mapping(source_names, target_names, mapping, (dataview_id, target_ds_id))
|
|
4092
4151
|
source_only = sorted(source_names - target_names - set(mapping))
|
|
4093
|
-
target_only =
|
|
4152
|
+
target_only = _blank_destination_columns(source_names, target_names, mapping)
|
|
4094
4153
|
source_types = service.call_view(dataview_id, "column_types", dataset_id=dataset_id)
|
|
4095
4154
|
_reject_append_type_mismatch(source_types, target_schema, mapping, (dataview_id, target_ds_id))
|
|
4096
4155
|
if source_only:
|
|
@@ -77,6 +77,9 @@ ERROR_SUMMARIES: dict[str, str] = {
|
|
|
77
77
|
"More than one item matched, so the assistant needs to be more specific."
|
|
78
78
|
),
|
|
79
79
|
"api_error": "Mammoth couldn't complete this step.",
|
|
80
|
+
"append_leaves_columns_blank": (
|
|
81
|
+
"This append would leave columns of the destination empty, and needs them named."
|
|
82
|
+
),
|
|
80
83
|
"append_mapping_incomplete": "The column mapping would leave columns out or add new ones.",
|
|
81
84
|
"append_schema_mismatch": "The new data doesn't line up with the existing columns.",
|
|
82
85
|
"append_type_mismatch": "A column has a different type than in the existing data.",
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"""The named opt-in for an append that leaves destination columns blank.
|
|
2
|
+
|
|
3
|
+
An append only writes the columns its mapping fills; every other destination
|
|
4
|
+
column is NULL in each appended row. The caller must name exactly those
|
|
5
|
+
columns in ``blank_columns`` -- the same explicit acknowledgement pattern as
|
|
6
|
+
``replace_table`` on a database export -- so a partial append is deliberate.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
import json
|
|
12
|
+
from typing import Any
|
|
13
|
+
|
|
14
|
+
from mammoth_cli.errors.envelope import EXIT_USAGE, CliError
|
|
15
|
+
|
|
16
|
+
BLANK_COLUMNS_FIELD = "blank_columns"
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def acknowledged_blank_columns(
|
|
20
|
+
destination_id: int, blank: list[str], acknowledged: Any
|
|
21
|
+
) -> list[str]:
|
|
22
|
+
"""Return the warnings for ``blank`` (empty when none), refusing an unnamed leave-blank.
|
|
23
|
+
|
|
24
|
+
``acknowledged`` is the input's ``blank_columns`` value; it must list
|
|
25
|
+
exactly the ``blank`` names as a set. A blanket ``true`` or a mismatched
|
|
26
|
+
list is refused with the expected list shown.
|
|
27
|
+
"""
|
|
28
|
+
if not blank:
|
|
29
|
+
return []
|
|
30
|
+
expected = sorted(blank)
|
|
31
|
+
given = (
|
|
32
|
+
{str(name) for name in acknowledged}
|
|
33
|
+
if isinstance(acknowledged, list) and not isinstance(acknowledged, bool)
|
|
34
|
+
else None
|
|
35
|
+
)
|
|
36
|
+
if given != set(expected):
|
|
37
|
+
listed = ", ".join(expected)
|
|
38
|
+
raise CliError(
|
|
39
|
+
code="append_leaves_columns_blank",
|
|
40
|
+
message=(
|
|
41
|
+
f"Appending into dataset {destination_id} leaves column(s) {listed} "
|
|
42
|
+
"blank (NULL) in every appended row."
|
|
43
|
+
),
|
|
44
|
+
exit_status=EXIT_USAGE,
|
|
45
|
+
hint=(
|
|
46
|
+
"If that is intended, add "
|
|
47
|
+
f'"{BLANK_COLUMNS_FIELD}": {_json_list(expected)} to the input to confirm; '
|
|
48
|
+
"otherwise map a source column to each of them."
|
|
49
|
+
),
|
|
50
|
+
details={"blank_columns": expected, "acknowledged": acknowledged},
|
|
51
|
+
)
|
|
52
|
+
return [f"appended rows leave column(s) {', '.join(expected)} blank (NULL), as confirmed"]
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def _json_list(names: list[str]) -> str:
|
|
56
|
+
"""The names as a JSON array literal, for the hint."""
|
|
57
|
+
return json.dumps(names)
|
|
@@ -743,6 +743,14 @@ _S7_ADDITIONAL_INPUT_FIELDS: dict[str, tuple[FieldSpec, ...]] = {
|
|
|
743
743
|
)
|
|
744
744
|
for route in ("postgres", "mysql", "mssql", "redshift", "bigquery", "publish-db")
|
|
745
745
|
},
|
|
746
|
+
# An append that leaves destination columns unfilled needs them named in
|
|
747
|
+
# ``blank_columns`` (CLI-side acknowledgement, never forwarded to the SDK).
|
|
748
|
+
**{
|
|
749
|
+
route: (
|
|
750
|
+
FieldSpec("blank_columns", required=False, annotation=list[str] | None, default=None),
|
|
751
|
+
)
|
|
752
|
+
for route in ("view.export.dataset", "batch.create")
|
|
753
|
+
},
|
|
746
754
|
# user.update previously pinned name/email here as a guess, from when
|
|
747
755
|
# UserProfileAPI.update took **fields and so had nothing introspectable.
|
|
748
756
|
# The SDK method is now typed (first_name, last_name -- the backend's
|
|
@@ -91,7 +91,7 @@ commands:
|
|
|
91
91
|
- CT-BATCH-CREATE-ERROR
|
|
92
92
|
draft_test: null
|
|
93
93
|
undo_test: null
|
|
94
|
-
known_restrictions: Every source column must be mapped to an existing destination column; the CLI reads both schemas and refuses (append_mapping_incomplete) an unmapped source column or a destination the dataset lacks, because the backend appends only mapped columns. The CLI sends each item's expected_destination_c_type as the destination's current type (never re-types it; an explicit different value is refused with append_type_mismatch) and warns in mapping_check.warnings when source and destination types differ. SOURCE_ID is a standalone dataset in the same project (4BATC010 INVALID_SOURCE_DATASET for a file id or an append child); to append a file use file upload with append_to_ds_id. delete_source_ds=true changes the mutation class to destructive and requires confirmation.
|
|
94
|
+
known_restrictions: Every source column must be mapped to an existing destination column; the CLI reads both schemas and refuses (append_mapping_incomplete) an unmapped source column or a destination the dataset lacks, because the backend appends only mapped columns. A destination column no mapping item fills (add_column items count) would be NULL in every appended row, so it is refused (append_leaves_columns_blank) unless the input lists exactly those names in blank_columns; the confirmed blanks are named in mapping_check.warnings. The CLI sends each item's expected_destination_c_type as the destination's current type (never re-types it; an explicit different value is refused with append_type_mismatch) and warns in mapping_check.warnings when source and destination types differ. SOURCE_ID is a standalone dataset in the same project (4BATC010 INVALID_SOURCE_DATASET for a file id or an append child); to append a file use file upload with append_to_ds_id. delete_source_ds=true changes the mutation class to destructive and requires confirmation.
|
|
95
95
|
reviewed_by: primary
|
|
96
96
|
readback:
|
|
97
97
|
command: batch.list
|
|
@@ -2261,7 +2261,7 @@ commands:
|
|
|
2261
2261
|
- CT-VIEW-EXPORT-DATASET-ERROR
|
|
2262
2262
|
draft_test: null
|
|
2263
2263
|
undo_test: null
|
|
2264
|
-
known_restrictions: 'Mutation class dynamic: benign_mutation for a new target, destructive when replacing an existing target. The export is appended to the source pipeline (end_of_pipeline) and re-runs with it; target_project_id sends the dataset into another project (cross-project branch-out, proven on release). Result: {dataset_id, project_id, source_view_id, next}. Not a plain copy: this leaves a live export on the source and the new dataset refreshes from the source view, so keep that working view and name it as the new dataset''s source. For an independent copy of a dataset use dataset create with ds_creation_type clone. Writing into an existing dataset (target_ds_id, save_as_mode APPEND_TO_DS or REPLACE_IN_DS; both run the same backend append code, so both get these guards): omit column_mapping and every column is mapped by name; a non-empty column_mapping is used as-is, so it must map every source column to an existing target column, and a partial mapping or an unknown destination is refused (append_mapping_incomplete) before anything is written. A mapped pair of different types is reported in row_check.warnings. A new dataset (no target_ds_id) leaves out the view''s hidden columns; they are named in row_check.warnings.'
|
|
2264
|
+
known_restrictions: 'Mutation class dynamic: benign_mutation for a new target, destructive when replacing an existing target. The export is appended to the source pipeline (end_of_pipeline) and re-runs with it; target_project_id sends the dataset into another project (cross-project branch-out, proven on release). Result: {dataset_id, project_id, source_view_id, next}. Not a plain copy: this leaves a live export on the source and the new dataset refreshes from the source view, so keep that working view and name it as the new dataset''s source. For an independent copy of a dataset use dataset create with ds_creation_type clone. Writing into an existing dataset (target_ds_id, save_as_mode APPEND_TO_DS or REPLACE_IN_DS; both run the same backend append code, so both get these guards): omit column_mapping and every column is mapped by name; a non-empty column_mapping is used as-is, so it must map every source column to an existing target column, and a partial mapping or an unknown destination is refused (append_mapping_incomplete) before anything is written. A target column that nothing fills (a column the source view lacks and column_mapping does not target) would be NULL in every appended row: refused (append_leaves_columns_blank) unless the input lists exactly those column names in blank_columns (a blanket true or a different list is refused); the confirmed blanks are named in row_check.warnings. Do not reshape the source view to dodge this. A mapped pair of different types is reported in row_check.warnings. A new dataset (no target_ds_id) leaves out the view''s hidden columns; they are named in row_check.warnings.'
|
|
2265
2265
|
reviewed_by: primary
|
|
2266
2266
|
- command_id: view.export.delete
|
|
2267
2267
|
command_path: view export delete
|
|
@@ -3752,7 +3752,7 @@ commands:
|
|
|
3752
3752
|
- CT-VIEW-PIPELINE-RERUN-ERROR
|
|
3753
3753
|
draft_test: null
|
|
3754
3754
|
undo_test: null
|
|
3755
|
-
known_restrictions: 'A rerun fires every end-of-pipeline export of the view again (database, email, REST, dataset); the result lists them in exports_fired (export_id, handler_type, target) so the external effect is visible.'
|
|
3755
|
+
known_restrictions: 'A rerun fires every end-of-pipeline export of the view again (database, email, REST, dataset); the result lists them in exports_fired (export_id, handler_type, target) so the external effect is visible. --dry-run returns the same exports_fired without running. An internal_dataset export that appends or replaces into an existing dataset also carries blank_columns: the sorted destination column names the write would leave NULL ([] when none).'
|
|
3756
3756
|
reviewed_by: primary
|
|
3757
3757
|
- command_id: view.pipeline.wait
|
|
3758
3758
|
command_path: view pipeline wait
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/bundled_skill/mammoth-cli/references/auth.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mammoth_cli-2.2.31 → mammoth_cli-2.2.33}/mammoth_cli/bundled_skill/mammoth-cli/references/input.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|