Switch to unified view

a b/docs/explanation/vscode-extension.md
1
# The OpenSAFELY VS Code Extension
2
3
This page describes how to install and use the OpenSAFELY VS Code extension to assist in
4
learning and writing ehrQL.
5
6
## What does the extension do?
7
8
It uses a set of local dummy tables to allow you to inspect the contents of ehrQL tables, columns,
9
datasets and queries. This means you can use known data (the contents of your dummy tables) to
10
check if your ehrQL queries are extracting data as you expect.
11
12
e.g. given a dummy patient table
13
14
|patient_id|date_of_birth|
15
|----------|-------------|
16
|1         | 1990-01-01  |
17
|2         | 1980-01-01  |
18
19
```py
20
show(patients.age_on("2020-01-01"))
21
```
22
would display
23
24
|patient_id|value|
25
|----------|-----|
26
|1         | 30  |
27
|2         | 40  |
28
29
## Installation
30
31
### Check if the extension is already installed
32
33
You can check if the extension is already installed by opening an ehrQL dataset definition
34
file in VS Code. With the file open, click on the the dropdown next to the Run button. If the extension is installed, the first (default) option in the dropdown menu will be "OpenSAFELY: Debug ehrQL dataset".
35
![Run button dropdown](vscode_extension_run_button_dropdown.png)
36
37
### Working in Codespaces
38
If you are [creating a new repo from the research template](https://docs.opensafely.org/getting-started/tutorial/create-a-github-repository/), the extension will already be
39
installed when you start up a codespace.
40
41
If you have an existing repo that does not have the extension installed, follow the
42
[instructions to update your codespace](https://docs.opensafely.org/getting-started/how-to/update-github-codespaces-in-your-project/).
43
44
### Working locally on your own computer
45
46
Click on the Extensions icon in the left hand menu bar in VS Code, or go to
47
File > Preferences > Extensions.
48
49
![VS Code Extensions icon](vscode_extensions_icon.png)
50
51
This will display a list of installed and available
52
extensions. Search for "opensafely" to find the OpenSAFELY extension.
53
54
![VS Code Extensions search](vscode_extension_search.png)
55
56
### Updating the extension
57
In a Codespace, updates to the extension will be installed automatically the next time
58
your codespace starts up. Locally, you will see a notification on the Extensions icon when
59
you have extensions with updates available, and you will need to manually click on the
60
"Restart extension" button link to install the updated extension.
61
![VS Code Extensions icon with updates](vscode_extensions_icon_updates.png)
62
63
## Using the extension
64
65
### Dummy tables
66
67
The extension requires a folder containing dummy tables. By default, this is expected
68
to be called `dummy_tables`, and located at the top level of your study repo folder. The
69
location can be configured in the extension settings.
70
71
ehrQL provides some example data for the core ehrQL tables, which you can fetch by
72
running
73
```
74
opensafely exec ehrql:v1 dump-example-data
75
```
76
77
This will create a folder called `example-data`, which you can rename to `dummy_tables` for
78
use by the extension.
79
80
Alternatively you can [supply your own dummy tables](../how-to/dummy-data.md#supply-your-own-dummy-tables) or use your dataset definition to
81
[generate dummy tables for you](../how-to/dummy-data.md#generating-dummy-tables).
82
83
To generate dummy tables from a dataset definition, `dataset_definition.py`, and
84
save them to a folder called `dummy_tables`:
85
```
86
opensafely exec ehrql:v1 create-dummy-tables dataset_definition.py dummy_tables
87
```
88
89
### The show() function
90
91
We can show the contents of an ehrQL dataset, table, column or query by using the `show()`.
92
93
Import the function:
94
95
```py
96
from ehrql import show
97
```
98
Show the contents of an ehrQL element:
99
```py
100
show(<element>)
101
```
102
103
Click on the Run button, or Ctrl+Shift+P and select the "OpenSAFELY: Debug ehrQL dataset"
104
command.
105
![Run button](vscode_extension_run_button.png)
106
107
The following dataset definition filters patients to only those over 18, and shows the
108
`age` variable and the corresponding date of birth value from the `patients` table (with an optional label), and the final dataset output.
109
110
```ehrql
111
from ehrql import create_dataset, show
112
from ehrql.tables.core import patients
113
114
age = patients.age_on("2022-01-01")
115
116
show(age, patients.date_of_birth, label="Age")
117
dataset = create_dataset()
118
dataset.define_population(age >= 18)
119
dataset.age = age
120
show(dataset)
121
```
122
123
Running the extension opens an adjacent panel to display the contents of the `show()` calls.
124
125
![ehrQL debug output](vscode_extension_ehrql_debug.png)
126
127
### Showing multiple variables
128
129
As we saw in the example above, `show()` can be called with multiple ehrQL elements; in this
130
case, `age`, and `date_of_birth` from the `patients` table. These both contain one row per
131
patient, and are shown in a single table.
132
133
We can `show()` any number of one-row-per-patient ehrQL series in a single output table, e.g.:
134
135
```py
136
show(patients.sex, clinical_events.count_for_patient())
137
```
138
139
Or multiple many-rows-per-patient ehrQL series, *as long as they come from the same table*.
140
141
```py
142
show(clinical_events.date, clinical_events.numeric_value)
143
```
144
145
### Troubleshooting
146
147
#### Invalid combinations of elements
148
Attempting to use `show()` with a combination of one-row-per-patient and many-rows-per-patient
149
series with raise an error.
150
151
e.g. The following is invalid:
152
```py
153
show(patients.sex, clinical_events.date)
154
```
155
156
Instead, show these series separately:
157
```py
158
show(patients.sex)
159
show(clinical_events.date)
160
```
161
162
The tables will be displayed one after another in the output panel.
163
164
#### Errors in ehrQL
165
166
If you write some invalid ehrQL in your dataset definition, you will see an error message
167
printed to the display panel:
168
169
```py
170
show(
171
    medications.where(medications.date >= "2016-01-01").sort_by(medications.dat).first_for_patient()
172
)
173
```
174
175
```
176
Error loading file 'dataset_definition.py':
177
178
Traceback (most recent call last):
179
  File "/home/becky/datalab/ehrql/dataset_definition.py", line 21, in <module>
180
    medications.where(medications.date >= "2016-01-01").sort_by(medications.dat).first_for_patient()
181
                                                                ^^^^^^^^^^^^^^^
182
AttributeError: 'medications' object has no attribute 'dat'
183
```
184
185
:grey_question: Can you work out what this is telling us?
186
187
Refer to [the catalogue of errors](../how-to/errors.md) for details of common error messages and what they mean.