You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/concepts/models/overview.md
+2-56Lines changed: 2 additions & 56 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -95,38 +95,7 @@ MODEL (
95
95
```
96
96
97
97
## Macros
98
-
Macros can be used for passing in paramaterized arguments such as dates, as well as for making SQL less repetitive. By default, SQLMesh provides several predefined macro variables that can be used. Macros are used by prefixing with the `@` symbol.
99
-
100
-
- @start_date
101
-
```sql
102
-
-- The inclusive start interval of an execution casted to a DATETIME SQL object.
Macros can be used for passing in paramaterized arguments such as dates, as well as for making SQL less repetitive. By default, SQLMesh provides several predefined macro variables that can be used. Macros are used by prefixing with the `@` symbol. For more information, refer to [macros](../../concepts/macros.md).
130
99
131
100
## Statements
132
101
Models can have additional statements that run before the main query. This can be useful for loading things such as [UDFs](https://en.wikipedia.org/wiki/User-defined_function). In general, statements should only be used for preparing the main query. They should not be used for creating or altering tables, as this could lead to unpredictable behavior.
@@ -144,30 +113,7 @@ FROM y
144
113
```
145
114
146
115
## Time column
147
-
Models that are loaded incrementally require a time column to partition data. A time column is a column in a model with an optional format string in the dialect of the model; for example, `'%Y-%m-%d'` for DuckDB or `'yyyy-mm-dd'` for Snowflake.
148
-
149
-
```sql linenums="1"
150
-
-- Orders are partitioned by the ds column
151
-
MODEL (
152
-
name sushi.orders,
153
-
dialect duckdb,
154
-
kind INCREMENTAL_BY_TIME_RANGE (
155
-
time_column (ds, '%Y-%m-%d')
156
-
)
157
-
);
158
-
159
-
SELECT
160
-
id::INTAS id, -- Primary key
161
-
customer_id::INTAS customer_id, -- Id of customer who made the order
162
-
waiter_id::INTAS waiter_id, -- Id of waiter who took the order
163
-
start_ts::TEXTAS start_ts, -- Start timestamp
164
-
end_ts::TEXTAS end_ts, -- End timestamp
165
-
ds::TEXTAS ds -- Date of order
166
-
FROMraw.orders
167
-
WHERE
168
-
ds BETWEEN @start_ds AND @end_ds
169
-
```
170
-
When SQLMesh incrementally inserts data for a partition, it will overwrite any existing data in that partition. For engines that support partitions, it will use an `INSERT OVERWRITE` query. For engines that do not, it will first delete the data in the partition before inserting.
116
+
Models that are loaded incrementally require a time column to partition data. A time column is a column in a model with an optional format string in the dialect of the model; for example, `'%Y-%m-%d'` for DuckDB or `'yyyy-mm-dd'` for Snowflake. For more information, refer to [time column](../../concepts/models/model_kinds.md#time-column).
171
117
172
118
### Format string configuration
173
119
The format string tells SQLMesh how your dates are formatted in order to compare start and end dates correctly. You can configure a project-wide default format in your project configuration. A time column format string declared in a model will override the project-wide default. If the model uses a different dialect than the rest of your project, the format string will be automatically transpiled to the model dialect with SQLGlot. SQLMesh will use
Copy file name to clipboardExpand all lines: docs/concepts/tests.md
+33-18Lines changed: 33 additions & 18 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,24 +1,27 @@
1
1
# Testing
2
-
Testing is how you can protect your project from regression by continuously verifying that the output of each model matches the expectations. Unlike [audits](audits.md), tests are executed either on demand (eg. as part of a CI / CD job) or every time a new [plan](plans.md) is created.
3
2
4
-
Similarly to unit testing in software development, SQLMesh evaluates the model's logic against predefined inputs and compares the output to expected outcomes provided as part of each test.
3
+
Testing allows you to protect your project from regression by continuously verifying the output of each model matches your expectations. Unlike [audits](audits.md), tests are executed either on demand (for example, as part of a CI/CD job) or every time a new [plan](plans.md) is created.
5
4
6
-
A comprehensive suite of tests can empower data practitioners to work with confidence, since it allows them to make sure that models behave as expected after changes have been applied to them.
5
+
Similar to unit testing in software development, SQLMesh evaluates the model's logic against predefined inputs and then compares the output to expected outcomes provided as part of each test.
6
+
7
+
A comprehensive suite of tests can empower data practitioners to work with confidence, as it allows them to ensure models behave as expected after changes have been applied to them.
7
8
8
9
## Creating tests
9
-
Test suites are defined using YAML format in files with the `.yaml` extension as part of the `tests/` folder of your SQLMesh project. Each test within a suite file consists of the following attributes:
10
+
11
+
Test suites are defined using YAML format within `.yaml` files in the `tests/` folder of your SQLMesh project. Each test within a suite file contains the following attributes:
10
12
11
13
* The unique name of a test
12
-
* The name of the model that is targeted by this test
13
-
* Test inputs. Inputs are defined per external table or upstream model referenced by the target model. Each test input consists of the following:
14
+
* The name of the model targeted by this test
15
+
* Test inputs, which are defined per external table or upstream model referenced by the target model. Each test input consists of the following:
14
16
* The name of an upstream model or external table
15
17
* The list of rows defined as a mapping from a column name to a value associated with it
16
-
* Expected outputs which are defined as follows:
18
+
* Expected outputs, which are defined as follows:
17
19
* The list of rows that are expected to be returned by the model's query defined as a mapping from a column name to a value associated with it
18
-
*[Optional] The list of expected rows per each individual [Common Table Expression](glossary.md#cte) (CTE) defined in the model's query.
19
-
*[Optional] The dictionary of values for macro variables that will be set during model testing.
20
+
*[Optional] The list of expected rows per each individual [Common Table Expression](glossary.md#cte) (CTE) defined in the model's query
21
+
*[Optional] The dictionary of values for macro variables that will be set during model testing
20
22
21
23
The YAML format is defined as follows:
24
+
22
25
```yaml linenums="1"
23
26
<unique_test_name>:
24
27
model: <target_model_name>
@@ -38,9 +41,10 @@ The YAML format is defined as follows:
38
41
<macro_variable_name>: <macro_variable_value>
39
42
```
40
43
41
-
## Example
44
+
### Example
45
+
46
+
In this example, we'll use the `sqlmesh_example.example_full_model` model, which is provided as part of the `sqlmesh init` command and defined as follows:
42
47
43
-
In this example we'll use the `sqlmesh_example.example_full_model` model which is provided as part of the `sqlmesh init` command and is defined as follows:
44
48
```sql linenums="1"
45
49
MODEL (
46
50
name sqlmesh_example.example_full_model,
@@ -56,9 +60,10 @@ FROM
56
60
GROUP BY item_id
57
61
```
58
62
59
-
Notice how the query of the model definition above references one upstream model - `sqlmesh_example.example_incremental_model`.
63
+
Notice how the query of the model definition above references one upstream model:`sqlmesh_example.example_incremental_model`.
60
64
61
65
The test definition for this model may look like following:
66
+
62
67
```yaml linenums="1"
63
68
test_example_full_model:
64
69
model: sqlmesh_example.example_full_model
@@ -85,7 +90,8 @@ test_example_full_model:
85
90
86
91
### Testing CTEs
87
92
88
-
As mentioned previously, individual CTEs within the model's query can also be tested. In this example let's slightly modify the query of the model used in the previous example:
93
+
Individual CTEs within the model's query can also be tested. Let's slightly modify the query of the model used in the previous example:
94
+
89
95
```sql linenums="1"
90
96
WITH filtered_orders_cte AS (
91
97
SELECT
@@ -104,7 +110,8 @@ FROM
104
110
GROUP BY item_id
105
111
```
106
112
107
-
Below is the example of a test which verifies individual rows returned by the `filtered_orders_cte` CTE before aggregation takes place:
113
+
Below is the example of a test that verifies individual rows returned by the `filtered_orders_cte` CTE before aggregation takes place:
114
+
108
115
```yaml linenums="1" hl_lines="16-22"
109
116
test_example_full_model:
110
117
model: sqlmesh_example.example_full_model
@@ -135,10 +142,14 @@ test_example_full_model:
135
142
```
136
143
137
144
## Running tests
138
-
Tests run automatically every time a new [plan](plans.md) is created. Additionally tests can be run on demand using the `sqlmesh test` command.
139
145
140
-
### The CLI test command
141
-
You can execute tests using the `sqlmesh test` command as follows:
146
+
### Automatic testing with plan
147
+
148
+
Tests run automatically every time a new [plan](plans.md) is created.
149
+
150
+
### Manual testing with the CLI
151
+
152
+
You can execute tests on demand using the `sqlmesh test` command as follows:
142
153
```bash
143
154
$ sqlmesh test
144
155
.
@@ -148,7 +159,8 @@ Ran 1 test in 0.005s
148
159
OK
149
160
```
150
161
151
-
The command returns a non-zero exit code if on any failures and reports them in the standard error stream:
162
+
The command returns a non-zero exit code if there are any failures, and reports them in the standard error stream:
163
+
152
164
```bash
153
165
$ sqlmesh test
154
166
F
@@ -169,12 +181,15 @@ Ran 1 test in 0.008s
169
181
FAILED (failures=1)
170
182
```
171
183
184
+
### Testing for specific models
172
185
To run a specific model test, pass in the suite file name followed by `::` and the name of the test:
186
+
173
187
```
174
188
sqlmesh test tests/test_suite.yaml::test_example_full_model
175
189
```
176
190
177
191
You can also run tests that match a pattern or substring using a glob pathname expansion syntax:
As the unit tests run, SQLMesh will identify any that fail.
17
14
18
15
For more information about tests, refer to [testing](../concepts/tests.md).
19
16
20
17
### Test changes to a specific model
21
18
22
-
To run a specific model test, pass in the module followed by `::` and the name of the test.
23
-
24
-
For example: `example_full_model::test_example_full_model.`
19
+
To run a specific model test, pass in the suite file name followed by `::` and the name of the test; for example: `sqlmesh test tests/test_suite.yaml::test_example_full_model`.
25
20
26
21
### Run a subset of tests
27
22
28
-
To run a test that matches a pattern or substring, use the following syntax: `project.tests.test_order*`.
23
+
To run a test that matches a pattern or substring, use the following syntax: `sqlmesh test tests/test_example*`.
29
24
30
-
For example, this will match the following tests: `project.tests.test_orders`, `project.tests.test_order_items`.
25
+
Running the above command will run our `test_example_full_model` test that we ran earlier using `sqlmesh test`:
As another example, running the `sqlmesh test tests/test_order*` command would run the following tests:
37
+
38
+
*`test_orders`
39
+
*`test_orders_takeout`
40
+
*`test_order_items`
41
+
*`test_order_type`
42
+
43
+
## Auditing changes to models
34
44
To audit your models, run the `sqlmesh audit` command as follows:
35
45
36
46
```bash
@@ -41,7 +51,6 @@ assert_positive_order_ids PASS.
41
51
Finished with 0 audit error(s).
42
52
Done.
43
53
```
44
-
45
54
**Note:** Ensure that you have already planned and applied your changes before running an audit.
46
55
47
56
By default, SQLMesh will halt the pipeline when an audit fails in order to prevent potentially invalid data from propagating further downstream. This behavior can be changed for individual audits by defining them as [non-blocking](../concepts/audits.md#non-blocking-audits).
0 commit comments