duckdb-session
Skill1 starsChanged 14 days agoMITView on GitHub
Attach native DuckDB database files and persist session state across CLI calls with a state.sql init file. Covers storage version detection, schema introspection, WAL checkpoints, locking, and safe detach. Use when attaching or opening a database, switching catalogs, or persisting state across commands.
In this repository14 other files it gives its agents.
- duckdb-dbtSkill
- duckdb-docsSkill
- duckdb-extensionsSkill
- duckdb-filesSkill
- duckdb-lakehouseSkill
- duckdb-migrateSkill
- duckdb-profileSkill
- duckdb-pythonSkill
- duckdb-quackSkill
- duckdb-searchSkill
- duckdbSkill
- duckdb-spatialSkill
- duckdb-sqlSkill
- duckdb-variantSkill
The file
Show its rules and text
We split this skill into the rules it gives an agent
13 rules. About 0 are common, 3 are distinctive, and 10 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈3
Distinctive · estimate
This author's own choices. Worth a look.
10
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 16
Never store raw secrets in the state file.
- Distinctive: line 20
Search for a state file in this exact sequence:
- Distinctive: line 26
If no state file exists:
- Very specific: line 27
When the project root is $HOME, create $HOME/.duckdb-skills/state.sql to avoid colliding with ~/.duckdb/.
- Very specific: line 28
When session persistence belongs outside the repository, write to the $HOME/.duckdb-skills/<project-id>/ location.
- Very specific: line 33
Treat the state file as append-only.
- Distinctive: line 38
If alias and path match: skip the attachment.
- Very specific: line 39
If alias matches but points to a different path: halt and ask the user.
- Very specific: line 40
If path matches under a second alias: halt.
- Very specific: line 41
Guard missing files: Before attaching a nonexistent path, verify with test -f.
- Very specific: line 43
Validate lifecycle: Test the state file in a fresh process without -init, then with -init.
- Very specific: line 63
If the user requested a default catalog or the state file lacks a USE command, append USE analytics;.
- Very specific: line 107
If schemas are nested, join duckdb_tables() with duckdb_schemas() on both schema and database OIDs:
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Database sessions
DuckDB CLI executions terminate after each command, discarding runtime ATTACH bindings. To persist attached databases across invocations, record attachment statements in an initialization script and pass -init <path> on startup.
For execution binary rules, see duckdb. For SQLite databases, see duckdb-files. For DuckLake, Iceberg, and Delta catalogs, see duckdb-lakehouse. For Quack, Postgres, and MySQL connections, see duckdb-quack.
Never store raw secrets in the state file. Record only ATTACH commands and CREATE SECRET statements referencing an external provider chain or pre-existing secret name.
State file discovery
Search for a state file in this exact sequence:
.duckdb/state.sqlin the project root..duckdb-skills/state.sqlin the project root (upstream duckdb-skills plugin convention).$HOME/.duckdb-skills/<project-id>/state.sql(<project-id>replaces/with-in the absolute project root).
If no state file exists:
- When the project root is
$HOME, create$HOME/.duckdb-skills/state.sqlto avoid colliding with~/.duckdb/. - When session persistence belongs outside the repository, write to the
$HOME/.duckdb-skills/<project-id>/location. - Otherwise, create
.duckdb/state.sql, report the path to the user, and offer to add.duckdb/to.gitignore.
State file reconciliation
Treat the state file as append-only. Never overwrite or truncate it, as it may contain user macros, variables, and LOAD statements. Before appending, execute this reconciliation procedure:
- Read existing statements: Parse the file for existing
ATTACH,USE,LOAD,SET, andCREATE SECRETcommands. Never echo or display secret credentials. - Resolve and compare: Resolve each
ATTACHpath to an absolute path. Derive the alias from the filename up to the first dot (a.b.c.dbbecomesa). If the alias contains hyphens, spaces, or leading digits, enclose it in double quotes. Inspect attached catalogs viaduckdb_databases(). - Handle collisions:
- If alias and path match: skip the attachment.
- If alias matches but points to a different path: halt and ask the user.
ATTACH IF NOT EXISTSkeys on alias and silently retains the original path. - If path matches under a second alias: halt. DuckDB rejects duplicate paths with
Unique file handle conflict.
- Guard missing files: Before attaching a nonexistent path, verify with
test -f. DuckDB 2.0 creates missing files as storage version 69, unreadable by DuckDB 1.x. Confirm with the user before generating new files. - Append missing delta: Append only missing
ATTACHstatements. Maintain at most oneUSE <alias>;in the state file so subsequent attachments do not alter the active catalog. - Validate lifecycle: Test the state file in a fresh process without
-init, then with-init. Confirm expected catalogs appear induckdb_databases(). If external processes require file access, checkpoint and detach before handoff.
Attach semantics and options
To persist a database without mutating existing aliases, append:
ATTACH IF NOT EXISTS '/absolute/path/analytics.duckdb' AS analytics;Common attach options:
| Option | Function |
READ_ONLY | Mount files for concurrent readers or remote storage over HTTPS/S3. |
STORAGE_VERSION 'v1.5.6' | Create new storage version 68 files readable by DuckDB 1.5.6. DuckDB 1.4 cannot read them. v1.5.0 writes an identical header. |
ENCRYPTION_KEY '...' | Open an encrypted database. Load httpfs first for OpenSSL hardware acceleration. |
TYPE sqlite | Open a SQLite file. Hand off to duckdb-files. |
ATTACH OR REPLACE | Forcefully rebind an existing alias. Destructive; confirm with user first. |
If the user requested a default catalog or the state file lacks a USE command, append USE analytics;. Without an explicit USE, DuckDB defaults to memory, causing bare SHOW TABLES; to appear empty despite valid attachments.
The -init flag is CLI-specific; Python and client drivers must issue ATTACH programmatically. Init files execute both SQL and dot commands; any SQL or syntax error immediately aborts startup with exit code 1.
To validate attachment in isolation before persisting, run once directly, then verify with -init:
duckdb -json -c "ATTACH '/absolute/path/analytics.duckdb' AS analytics; SELECT database_name, path, tags['storage_version'] AS storage_version FROM duckdb_databases();"
duckdb -init .duckdb/state.sql -json -c "SHOW TABLES;"Storage version management
Inspect active storage versions via:
SELECT database_name, path, tags['storage_version'] AS storage_version, readonly, type
FROM duckdb_databases()
WHERE NOT internal;tags['storage_version'] reports the minimum compatibility floor, not raw internal integers. Storage version 69 reports v2.0.0+ (DuckDB 1.x cannot open). Storage version 68 reports v1.5.0+.
Opening a legacy 1.x file in DuckDB 2.0 does not upgrade it; standard reads and writes preserve existing storage versions in place. Upgrading an existing file to storage 69 occurs only when mounting via ATTACH '<path>' AS alias (STORAGE_VERSION 'latest'); followed by a write. Never pass STORAGE_VERSION 'latest' unless the user explicitly requested a file format upgrade. To pin formats for older readers, follow duckdb-migrate.
Catalog exploration
Introspect tables within the target catalog:
SELECT schema_name, table_name, estimated_size, column_count
FROM duckdb_tables()
WHERE database_name = 'analytics' AND NOT internal
ORDER BY schema_name, table_name;Inspect table schemas for up to 20 relevant tables:
DESCRIBE analytics.main.table_name;estimated_size represents an approximation. If the user requires exact row counts or estimated_size is small, run count(*).
If schemas are nested, join duckdb_tables() with duckdb_schemas() on both schema and database OIDs:
SELECT s.parent_schema, t.schema_name, t.table_name
FROM duckdb_tables() AS t
JOIN duckdb_schemas() AS s ON t.schema_oid = s.oid AND t.database_oid = s.database_oid
WHERE t.database_name = 'analytics' AND s.parent_schema IS NOT NULL;Report the absolute path, alias, state file path, storage version, and discovered tables. Pass -init with the state file in subsequent skill invocations.
Concurrency, durability, and detach
Across processes, native DuckDB files enforce single-writer or multi-reader exclusivity. A writer process locks the database against read-only processes, and an active reader blocks incoming writers. Within a single process, multiple connections share read-write access under MVCC, though opening a secondary connection with differing configuration (such as read_only=True) fails. For concurrent cross-process read and write access, hand off to duckdb-quack or duckdb-lakehouse.
To persist WAL changes to the database file:
CHECKPOINT analytics; -- Flush WAL to database file; fails if transactions are active
FORCE CHECKPOINT analytics; -- Wait for checkpoint lock, then flush (supported since 1.4)On clean process termination, DuckDB checkpoints and removes the WAL. The setting checkpoint_on_detach accepts ENABLED, DISABLED, or DEFAULT (not boolean values).
VACUUM does not shrink database files on disk. CHECKPOINT frees deleted-row storage blocks for internal reuse without guaranteeing file truncation. On legacy storage versions, checkpoint vacuum skips tables containing ART indexes unless vacuum_rebuild_indexes was configured at startup or attach time (deprecated fallback).
To release cross-process file locks, detach the database. DuckDB prevents detaching the active catalog; switch catalogs before detaching:
ATTACH ':memory:' AS memory_db;
USE memory_db;
DETACH analytics;Terminating the sole Python process releases database file locks. Because locks persist as long as any connection holds the file handle, explicitly issue DETACH in SQL when immediate lock release is required.
Copy, export, and sharing
To transfer schemas and data directly between catalogs:
COPY FROM DATABASE analytics TO archive;COPY FROM DATABASE requires an already-attached target catalog without conflicting table names; the destination database storage version governs the output file format.
To back up a database, target an empty directory: EXPORT DATABASE 'backup_dir' (FORMAT parquet);. Default export outputs SQL and CSV without purging existing files. To restore, ensure the target catalog contains no colliding objects and run IMPORT DATABASE 'backup_dir';. For cross-version format conversions, see duckdb-migrate.
To share datasets without distributing data files or credentials, publish a views-only catalog. A views-only catalog is a lightweight .duckdb file containing view definitions over remote object storage:
-- Publisher creates catalog
CREATE VIEW sales AS
SELECT * FROM read_parquet('s3://bucket/sales/*.parquet');
-- Consumer mounts catalog read-only
LOAD httpfs;
ATTACH 'https://example.com/catalog.duckdb' AS shared (READ_ONLY);
SELECT * FROM shared.sales;Consumers require direct read permissions and storage credentials for the underlying object store. Local file paths inside views work only when all consumers share identical filesystem paths. For secret management, see duckdb-files. For a hosted writable endpoint, see duckdb-quack.
Verify
Validate the state file and attached catalogs in an isolated CLI call:
duckdb -init .duckdb/state.sql -agent -c \
"SELECT database_name, tags['storage_version'] FROM duckdb_databases() WHERE NOT internal;"Confirm each configured alias appears exactly once with its expected storage version. Verify idempotency: repeated execution must not duplicate the ATTACH because the state file specifies ATTACH IF NOT EXISTS.
References
- ATTACH and DETACH defines syntax, flags, and storage constraints.
- CHECKPOINT documents WAL flushing and locking mechanisms.
- Concurrency covers process exclusivity and thread safety.
- Storage specifies storage version numbers and format compatibility.
- Views-only database details catalog sharing architectures.
- Reclaiming space covers WAL checkpoints and vacuum limitations.
- duckdb_databases catalogs system introspection functions.
duckdb_secrets()masks secret values while displayingkey_id. Log secret names and provider types only; never display row contents.- The state file pattern adapts the upstream
attach-dbskill from https://github.com/duckdb/duckdb-skills (MIT).
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

