#056: How to Run Queries from the Terminal (dbt Show Command)

workflow Dec 06, 2023

The dbt show command, added in dbt Core 1.5, compiles a model, runs it against your warehouse, and prints the first few rows directly in the terminal. Nothing is materialized and nothing is written to a file, so you can preview a model, inspect a column or chase a failing test without leaving your editor. You point it at a model with a selector, change the row count with a limit flag, or pass an inline query that uses ref to pick exactly the columns you want. It replaces the loop of copying compiled SQL into the database console just to see what a model returns. For small teams working in dbt Core it's one of the simplest workflow upgrades available.

Key takeaways

  • dbt show compiles a model, test or analysis, runs it, and previews the result in the terminal. It sits alongside run, build and test, with output on screen instead of a table in the warehouse.
  • The preview is never materialized. It isn't saved in the warehouse or in a file, only logged and displayed, so you can run it against a model you know is broken.
  • The default is five rows. The --limit flag changes that, and a small number is usually right because the output is inline in your terminal.
  • Wide tables get truncated. The --inline flag lets you write a select with ref and name only the columns you care about.
  • When a test fails, you can copy the test's logic into an inline query and see the offending rows without switching to the database UI.
  • It's a small command, but it removes the constant hopping between your editor and your warehouse during development.

What the dbt show command is

If you build models in dbt Core, you know the loop. You write SQL in your editor, run the model, then open the database console, paste in the compiled code, and look at the results to validate the data.

As of dbt 1.5 there's a command that shortcuts that. dbt show sits alongside dbt run, dbt build and dbt test.

It compiles the SQL definition of an object, which can be a model, a test or an analysis, runs it against the database, and previews the results in the terminal. By default it returns five rows.

Nothing gets materialized

The results of the preview query are not stored anywhere. They aren't materialized in the warehouse and they aren't written to a file. They're logged and displayed in the terminal, and that's it.

That matters for the test failure example later. You can preview a model you know is broken without creating or overwriting a table.

Two ways to use it

  • A selector. Point the command at an existing model, the same way you'd select one for a run or a test.
  • An inline query. Write your own select statement, use ref to point at a model, and pass it to the command as a string.

Both are below, in the order I'd learn them.

Using the command

Preview a model with a selector

Say I have a customers model I'm making changes to and I want to see what it returns. The command takes the same selector operator as run and test:

dbt show -s customers

-s is the short form of --select. dbt connects to the database using your default target, runs the compiled model, and prints the first five rows inline.

One thing you'll notice right away: it doesn't show every column. The terminal only has so much width, so a wide model gets cut off after the first six or so columns. The inline option further down is the answer to that.

What it runs against

The preview uses whatever target is the default in your profiles.yml. If you develop against a dev schema, you're looking at dev data, which is what you want: the state of your working copy, not production.

To preview against a different target, add --target the same way you would for a run.

Change the row count

Five rows is the default. The --limit flag adjusts it:

dbt show -s customers --limit 10

Now you get ten rows printed in the terminal. I wouldn't push this very high, since the output is inline and a few hundred rows in a terminal isn't useful to anyone. For a quick look at what a model produces, ten is plenty.

Query specific columns

Not seeing all the columns is a real limitation. Sometimes the columns you care about are the ones that got cut off, and sometimes you only want two or three of them anyway.

The inline flag

Instead of a selector, you can write a query and pass it with --inline. The ref function works inside it just like it does in a model file:

dbt show --inline "select * from {{ ref('customers') }}"

That's the example from the documentation with the model name swapped in. It still respects the row limit, and with a select star it still truncates columns. The point is that you now control what goes in the select list.

Investigating a test failure

This is where the command earns its place. In the demo, the customers model has a test on total_revenue_in_usd that requires the value to be positive. To force a failure, I multiplied the column by negative one and ran the model:

dbt run -s customers
dbt test -s customers

A dbt build would have done both steps at once. Either way, the test fails, and now I want to see the rows that caused it.

The old way is to open the compiled test SQL, hop over to the database server, paste it in and work through it there. Instead, I can go back to the inline query and pick the two columns that matter:

dbt show --inline "select customer_name, total_revenue_in_usd from {{ ref('customers') }}"

Right there in the terminal I can see the revenue values are negative, except for the zeros, which is exactly what the test caught.

Copy the test scenario

You can go further and add a where clause that mirrors the test condition:

dbt show --inline "select customer_name, total_revenue_in_usd from {{ ref('customers') }} where total_revenue_in_usd < 0"

Now the preview returns only the rows that fail. You've effectively copied the test scenario into a query and looked at the result without materializing anything or switching tools.

Customize it however you need. Add columns, change the filter, join to another ref. It's a normal query, it just runs from your terminal against your default target.

Where it fits in your workflow

This is a subtle command and it's easy to skip past it in the release notes. In practice it changes how often you leave your editor during a working session.

The three cases I use it for most:

  • Preview before deploying. See what a model returns before you run it, since the preview is never materialized.
  • Investigate a test failure. Reproduce the failing condition with an inline query and look at the rows.
  • Review records without changing screens. A quick check on a column or a count, without opening the warehouse UI.

None of these are hard to do the old way. They just cost a context switch each time, and over a day of development those add up.

Key terms

dbt show

A dbt Core command, available from version 1.5, that compiles a model, test or analysis, runs it against the warehouse and prints a preview of the rows in the terminal.

Selector

The -s or --select flag that tells a dbt command which node to operate on, shared by run, test, build and show.

Inline query

A select statement passed to dbt show with the --inline flag. It can use ref and runs in place of a selected model.

Default target

The connection in your profiles.yml that dbt uses when you don't specify one, and the database dbt show previews against.

Compiled SQL

The plain SQL dbt produces after resolving Jinja, refs and macros, which is what actually runs against the database.

Common questions

Does dbt show create a table in the warehouse?

No. The preview query runs against the database, but the results are only logged and displayed in the terminal. Nothing is materialized and nothing is written to a file, which is why it's safe to run against a model you're still fixing.

How many rows does dbt show return by default?

Five. Add --limit with a number to change it, for example dbt show -s customers --limit 10. Keep it small, since the output prints inline in your terminal.

Can I run a custom query with dbt show?

Yes. Pass a select statement as a string with the --inline flag. You can use ref inside it to point at any model in your project, pick specific columns, and add a where clause.

Why doesn't dbt show display all my columns?

The terminal has limited width, so a wide model gets cut off after the first handful of columns. Use an inline query to select only the columns you want to see instead of the whole table.

Which version of dbt do I need for dbt show?

dbt Core 1.5 or later. If the command isn't recognized, check dbt --version and upgrade the adapter package in your project's environment.

Can I use dbt show to debug a failing test?

Yes, and it's one of the best uses. Write an inline query that selects the tested column and filters on the test condition, such as values below zero. The preview returns the rows that fail without you leaving the terminal.

Related reading

Final takeaway

Most of what slows down a small dbt team isn't the SQL, it's the switching between tools to check it. dbt show keeps that check in the terminal you're already in, which is why it's the first command I point new dbt Core developers at once they're past run and test.

 

Additional Free Resources

Starter Guides & Checklists

Explore additional free resources built on the same patterns I use with real clients so you can build your own with structure and confidence. Topics include data architecture, modeling and more specifically for small data teams.

Browse Resources