What a Package Is and How to Install One
A dbt package is just another dbt project — with its own models, macros, tests, and seeds — that you install into your own project so you can call its macros or build on top of its models without copy-pasting code. You declare dependencies in a packages.yml file at your project root, listing each package's source (dbt Hub, a Git URL, or a local path) and version, then run dbt deps to download them into the dbt_packages/ directory.
Cricket analogy: This is like a franchise signing an overseas fast bowler on loan for a season rather than spending years developing an equivalent bowler from its own academy — you get proven capability by 'installing' outside talent.
# packages.yml
packages:
- package: dbt-labs/dbt_utils
version: [">=1.1.0", "<2.0.0"]
- package: calogica/dbt_expectations
version: [">=0.10.0", "<0.11.0"]
- git: "https://github.com/my-org/dbt-internal-macros.git"
revision: v2.3.0Using Package Macros and Tests
The most widely used package, dbt_utils, provides macros like generate_surrogate_key (hashing multiple columns into one deterministic key), date_spine (generating a gap-free calendar table), and pivot, all called with a package prefix like dbt_utils.generate_surrogate_key. dbt_utils and dbt_expectations also ship pre-built generic tests — dbt_utils.equal_rowcount, dbt_utils.not_accepted_values, dbt_expectations.expect_column_values_to_be_between — so you get statistically rigorous data quality checks referenced from schema.yml exactly like a built-in test.
Cricket analogy: This is like a franchise's analytics team using a licensed, industry-standard win-probability model instead of building their own from scratch, called by a simple function whenever needed during a broadcast.
-- models/marts/fct_orders.sql
select
{{ dbt_utils.generate_surrogate_key(['order_source', 'source_order_id']) }} as order_id,
order_date,
customer_id,
amount
from {{ ref('stg_orders') }}# schema.yml — using a package-provided generic test
columns:
- name: amount
tests:
- dbt_utils.accepted_range:
min_value: 0
max_value: 100000Version Pinning and Package Management
Version ranges in packages.yml, like [">=1.1.0", "<2.0.0"], protect you from a breaking major-version upgrade silently changing macro behavior underneath your project, while still letting patch and minor updates flow in automatically on the next dbt deps run. package-lock.yml, generated automatically alongside dbt deps, pins the exact resolved version actually installed, giving your team and CI environment a reproducible, identical set of package versions the same way a lockfile does in npm or pip.
Cricket analogy: This is like a franchise locking in a specific season's playing conditions regulations rather than automatically adopting every mid-season ICC rule change, while still applying agreed minor clarifications as they're issued.
Always commit package-lock.yml to version control alongside packages.yml — without it, two developers (or your local machine versus CI) could resolve slightly different package versions on dbt deps, leading to subtle, hard-to-reproduce test or macro behavior differences.
Private packages referenced via a git: URL with a plain HTTPS path will fail to clone in CI environments without stored credentials — use an SSH URL or a token-embedded HTTPS URL, and never commit that token directly into packages.yml; use environment variable substitution instead.
- A dbt package is a full dbt project (models, macros, tests) installed into yours via packages.yml and
dbt deps. - Packages can come from the dbt Hub, a public/private Git URL, or a local filesystem path.
- dbt_utils and dbt_expectations are the most widely used packages, providing macros and pre-built generic tests.
- Package macros are called with a namespace prefix, e.g. dbt_utils.generate_surrogate_key or dbt_utils.date_spine.
- Package-provided tests are referenced from schema.yml with the same prefix, e.g. dbt_utils.accepted_range.
- Version ranges in packages.yml prevent breaking major upgrades while allowing safe patch/minor updates.
- package-lock.yml pins exact resolved versions and should be committed for reproducible installs across environments.
Practice what you learned
1. What command downloads packages listed in packages.yml into the dbt_packages/ directory?
2. How do you call a macro provided by the dbt_utils package inside a model?
3. What is the purpose of package-lock.yml?
4. Why use a version range like [">=1.1.0", "<2.0.0"] instead of pinning to one exact version?
5. How can you install a private, internal package that isn't published to the dbt Hub?
Was this page helpful?
You May Also Like
Custom Data Tests
When the four built-in generic tests aren't enough, dbt lets you write singular tests as standalone SQL files or custom generic tests as reusable, parameterized macros.
Schema Tests
Schema tests are YAML-declared assertions — unique, not_null, accepted_values, and relationships — that dbt compiles into SQL to automatically validate your data on every run.
Documentation with dbt docs
dbt turns descriptions in your YAML files and standalone doc blocks into a browsable, auto-generated documentation site with an interactive lineage graph.
Related Reading
Related Study Notes in Programming
Browse all study notesApache Spark Study Notes
Programming · 30 topics
ProgrammingApache Flink Study Notes
Programming · 30 topics
ProgrammingHadoop Study Notes
Programming · 30 topics
ProgrammingSnowflake Study Notes
Programming · 30 topics
ProgrammingApache Airflow Study Notes
Programming · 30 topics
ProgrammingPowerShell Study Notes
Programming · 30 topics