Interactive SQL and PySpark Notebooks | Powered by DuckDB
DuckLab for VS Code provides data analysis features for SQL, PySpark and Python. It uses DuckDB to process your data locally.
db variable in python)duckdb.experimental.spark module (exposed as spark, a SparkSession instance)..py notebooks and preview in a user-friendly VS Code Notebook window..isql format. This format is plain text and human readable.ipynb format which stores cell outputs in the file and pollutes git. It also makes diff in pull requests unreadable..isql file.SQL Onlyselect * from 'data/MOCK_DATA.csv';The SQL Only kernel stores each notebook’s database in ~/.ducklab (the .ducklab directory in your home directory). Ducklab creates this directory automatically when opening the database. Existing databases in the system temporary directory are not migrated automatically.
The SQL Only kernel uses ducklab as its default database name. Set ducklab.databaseName in VS Code user or workspace settings to customize it:
{
"ducklab.databaseName": "ducklab"
}
Close and reopen the notebook after changing this setting. Each notebook keeps its original independent database file and existing data; only its SQL catalog alias changes. Update queries that explicitly qualify tables with the previous database name. Names must start with a letter or underscore and contain only letters, digits, and underscores; memory, system, and temp are reserved (case-insensitive).
The file is attached under the configured alias and selected as the default database, so current_database() returns that name and unqualified tables are stored there. An additional internal memory database appears in database/schema listings. Python/SQL and PySpark/SQL are unchanged.
To load a trusted unsigned extension, enable Ducklab: Allow Unsigned Extensions in VS Code User Settings, or add the following to your user settings:
{
"ducklab.allowUnsignedExtensions": true
}
This setting defaults to false and applies to SQL Only, Python/SQL, and PySpark/SQL kernels. It sets DuckDB’s startup option allow_unsigned_extensions, equivalent to the CLI -unsigned flag. Reload the VS Code window after changing it. This is a user-level setting, not a workspace setting.
Unsigned extensions execute native code with your user permissions. Only enable this for extensions you trust. PySpark/SQL uses a configured SparkContext connection when enabled because DuckDB’s experimental Spark builder does not apply config() options.
Place a .env file next to the .isql notebook to provide values for SQL cells. Ducklab expands $NAME and ${NAME} before running SQL in the SQL Only, Python/SQL, and PySpark/SQL kernels. Python cells are not modified. The .env file is re-read for each SQL cell; its values override matching extension process environment variables. If a referenced name is missing from both sources, execution stops and reports the missing name.
For example, copy sample/.env.example to the directory containing your notebook and use:
ATTACH 'host=$PGHOST dbname=$PGDATABASE user=$PGUSER password=$PGPASSWORD' AS duckspm (TYPE postgres);
Keep credentials in .env, which is ignored by Git. Variable values are substituted as SQL text and must be valid in the surrounding SQL syntax.
Single-query tabular results use backend pagination in the SQL Only, Python/SQL, and PySpark/SQL kernels. Only the visible page is sent to the interactive table; page navigation, global search, column filters, sorting, row counts, and Explore statistics are evaluated by the kernel. Value-filter suggestions are loaded on demand and capped at 200 per search. CSV export fetches the filtered result in pages. DDL and multi-statement cells keep their existing output behavior.


.isql file.Python/SQLducklab-python kernel will have db variable (duckdb connection) already initialized for you..isql file.PySpark/SQLducklab-spark kernel will have spark variable (SparkSession) already initialized for you.import pandas as pd
from duckdb.experimental.spark.sql.functions import lit, col
pandas_df = pd.DataFrame({
'age': [34, 45, 23, 56],
'name': ['Joan', 'Peter', 'John', 'Bob']
})
df = spark.createDataFrame(pandas_df)
df = df.withColumn(
'location', lit('Seattle')
)
df = df.select(
col('age'),
col('location')
)
display(df)
.py notebook fileImport Databricks NotebookContributions are most welcome. There are various ways you can contribute,
Use pnpm 10.33.3 and run pnpm install --frozen-lockfile from vs-extension. The checked-in pnpm-workspace.yaml approves installation scripts only for @vscode/vsce-sign, keytar, and zeromq, so CI does not require interactive pnpm approve-builds. Review any new dependency build scripts before adding them to this list.
VSIX packages retain only their target operating system’s native binaries under extension/build: Darwin packages exclude Linux and Windows binaries, Linux packages exclude Darwin and Windows binaries, and Windows packages exclude Darwin and Linux binaries.