duckdb-sqlalchemy 1.5.2.2__tar.gz → 1.5.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {duckdb_sqlalchemy-1.5.2.2 → duckdb_sqlalchemy-1.5.4}/.github/workflows/pythonapp.yaml +1 -0
- {duckdb_sqlalchemy-1.5.2.2 → duckdb_sqlalchemy-1.5.4}/.pre-commit-config.yaml +2 -2
- {duckdb_sqlalchemy-1.5.2.2 → duckdb_sqlalchemy-1.5.4}/CHANGELOG.md +41 -0
- {duckdb_sqlalchemy-1.5.2.2 → duckdb_sqlalchemy-1.5.4}/PKG-INFO +6 -5
- {duckdb_sqlalchemy-1.5.2.2 → duckdb_sqlalchemy-1.5.4}/README.md +2 -2
- {duckdb_sqlalchemy-1.5.2.2 → duckdb_sqlalchemy-1.5.4}/docs/configuration.md +2 -1
- {duckdb_sqlalchemy-1.5.2.2 → duckdb_sqlalchemy-1.5.4}/docs/connection-urls.md +9 -0
- {duckdb_sqlalchemy-1.5.2.2 → duckdb_sqlalchemy-1.5.4}/docs/motherduck.md +1 -0
- {duckdb_sqlalchemy-1.5.2.2 → duckdb_sqlalchemy-1.5.4}/docs/olap.md +123 -5
- {duckdb_sqlalchemy-1.5.2.2 → duckdb_sqlalchemy-1.5.4}/duckdb_sqlalchemy/__init__.py +199 -146
- duckdb_sqlalchemy-1.5.4/duckdb_sqlalchemy/_arrow.py +39 -0
- {duckdb_sqlalchemy-1.5.2.2 → duckdb_sqlalchemy-1.5.4}/duckdb_sqlalchemy/_bulk_insert.py +9 -2
- duckdb_sqlalchemy-1.5.4/duckdb_sqlalchemy/_statements.py +75 -0
- {duckdb_sqlalchemy-1.5.2.2 → duckdb_sqlalchemy-1.5.4}/duckdb_sqlalchemy/datatypes.py +27 -20
- {duckdb_sqlalchemy-1.5.2.2 → duckdb_sqlalchemy-1.5.4}/duckdb_sqlalchemy/motherduck.py +12 -4
- duckdb_sqlalchemy-1.5.4/duckdb_sqlalchemy/olap.py +721 -0
- {duckdb_sqlalchemy-1.5.2.2 → duckdb_sqlalchemy-1.5.4}/duckdb_sqlalchemy/tests/test_core_units.py +491 -8
- {duckdb_sqlalchemy-1.5.2.2 → duckdb_sqlalchemy-1.5.4}/duckdb_sqlalchemy/tests/test_execution_options.py +9 -0
- {duckdb_sqlalchemy-1.5.2.2 → duckdb_sqlalchemy-1.5.4}/duckdb_sqlalchemy/tests/test_helpers.py +83 -3
- {duckdb_sqlalchemy-1.5.2.2 → duckdb_sqlalchemy-1.5.4}/examples/motherduck_arrow_reads.py +2 -1
- {duckdb_sqlalchemy-1.5.2.2 → duckdb_sqlalchemy-1.5.4}/llms.txt +1 -1
- {duckdb_sqlalchemy-1.5.2.2 → duckdb_sqlalchemy-1.5.4}/noxfile.py +7 -7
- {duckdb_sqlalchemy-1.5.2.2 → duckdb_sqlalchemy-1.5.4}/pyproject.toml +4 -3
- {duckdb_sqlalchemy-1.5.2.2 → duckdb_sqlalchemy-1.5.4}/uv.lock +567 -524
- duckdb_sqlalchemy-1.5.2.2/duckdb_sqlalchemy/olap.py +0 -61
- {duckdb_sqlalchemy-1.5.2.2 → duckdb_sqlalchemy-1.5.4}/.codex/environments/environment.toml +0 -0
- {duckdb_sqlalchemy-1.5.2.2 → duckdb_sqlalchemy-1.5.4}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {duckdb_sqlalchemy-1.5.2.2 → duckdb_sqlalchemy-1.5.4}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {duckdb_sqlalchemy-1.5.2.2 → duckdb_sqlalchemy-1.5.4}/.github/dependabot.yml +0 -0
- {duckdb_sqlalchemy-1.5.2.2 → duckdb_sqlalchemy-1.5.4}/.github/workflows/lint.yml +0 -0
- {duckdb_sqlalchemy-1.5.2.2 → duckdb_sqlalchemy-1.5.4}/.github/workflows/pages.yml +0 -0
- {duckdb_sqlalchemy-1.5.2.2 → duckdb_sqlalchemy-1.5.4}/.github/workflows/publish.yaml +0 -0
- {duckdb_sqlalchemy-1.5.2.2 → duckdb_sqlalchemy-1.5.4}/.gitignore +0 -0
- {duckdb_sqlalchemy-1.5.2.2 → duckdb_sqlalchemy-1.5.4}/AGENTS.md +0 -0
- {duckdb_sqlalchemy-1.5.2.2 → duckdb_sqlalchemy-1.5.4}/ARCHITECTURE.md +0 -0
- {duckdb_sqlalchemy-1.5.2.2 → duckdb_sqlalchemy-1.5.4}/CLAUDE.md +0 -0
- {duckdb_sqlalchemy-1.5.2.2 → duckdb_sqlalchemy-1.5.4}/CODE_OF_CONDUCT.md +0 -0
- {duckdb_sqlalchemy-1.5.2.2 → duckdb_sqlalchemy-1.5.4}/LICENSE.txt +0 -0
- {duckdb_sqlalchemy-1.5.2.2 → duckdb_sqlalchemy-1.5.4}/PLANS.md +0 -0
- {duckdb_sqlalchemy-1.5.2.2 → duckdb_sqlalchemy-1.5.4}/ROADMAP.md +0 -0
- {duckdb_sqlalchemy-1.5.2.2 → duckdb_sqlalchemy-1.5.4}/codecov.yml +0 -0
- {duckdb_sqlalchemy-1.5.2.2 → duckdb_sqlalchemy-1.5.4}/docs/README.md +0 -0
- {duckdb_sqlalchemy-1.5.2.2 → duckdb_sqlalchemy-1.5.4}/docs/_config.yml +0 -0
- {duckdb_sqlalchemy-1.5.2.2 → duckdb_sqlalchemy-1.5.4}/docs/alembic.md +0 -0
- {duckdb_sqlalchemy-1.5.2.2 → duckdb_sqlalchemy-1.5.4}/docs/exec-plans/active/2026-03-27-maintenance-review.md +0 -0
- {duckdb_sqlalchemy-1.5.2.2 → duckdb_sqlalchemy-1.5.4}/docs/exec-plans/active/2026-03-30-maintenance-review.md +0 -0
- {duckdb_sqlalchemy-1.5.2.2 → duckdb_sqlalchemy-1.5.4}/docs/exec-plans/active/2026-03-31-maintenance-review.md +0 -0
- {duckdb_sqlalchemy-1.5.2.2 → duckdb_sqlalchemy-1.5.4}/docs/getting-started.md +0 -0
- {duckdb_sqlalchemy-1.5.2.2 → duckdb_sqlalchemy-1.5.4}/docs/index.md +0 -0
- {duckdb_sqlalchemy-1.5.2.2 → duckdb_sqlalchemy-1.5.4}/docs/migration-from-duckdb-engine.md +0 -0
- {duckdb_sqlalchemy-1.5.2.2 → duckdb_sqlalchemy-1.5.4}/docs/overview.md +0 -0
- {duckdb_sqlalchemy-1.5.2.2 → duckdb_sqlalchemy-1.5.4}/docs/pandas-jupyter.md +0 -0
- {duckdb_sqlalchemy-1.5.2.2 → duckdb_sqlalchemy-1.5.4}/docs/robots.txt +0 -0
- {duckdb_sqlalchemy-1.5.2.2 → duckdb_sqlalchemy-1.5.4}/docs/seo-checklist.md +0 -0
- {duckdb_sqlalchemy-1.5.2.2 → duckdb_sqlalchemy-1.5.4}/docs/types-and-caveats.md +0 -0
- {duckdb_sqlalchemy-1.5.2.2 → duckdb_sqlalchemy-1.5.4}/duckdb_sqlalchemy/_query.py +0 -0
- {duckdb_sqlalchemy-1.5.2.2 → duckdb_sqlalchemy-1.5.4}/duckdb_sqlalchemy/_supports.py +0 -0
- {duckdb_sqlalchemy-1.5.2.2 → duckdb_sqlalchemy-1.5.4}/duckdb_sqlalchemy/_validation.py +0 -0
- {duckdb_sqlalchemy-1.5.2.2 → duckdb_sqlalchemy-1.5.4}/duckdb_sqlalchemy/bulk.py +0 -0
- {duckdb_sqlalchemy-1.5.2.2 → duckdb_sqlalchemy-1.5.4}/duckdb_sqlalchemy/capabilities.py +0 -0
- {duckdb_sqlalchemy-1.5.2.2 → duckdb_sqlalchemy-1.5.4}/duckdb_sqlalchemy/config.py +0 -0
- {duckdb_sqlalchemy-1.5.2.2 → duckdb_sqlalchemy-1.5.4}/duckdb_sqlalchemy/conftest.py +0 -0
- {duckdb_sqlalchemy-1.5.2.2 → duckdb_sqlalchemy-1.5.4}/duckdb_sqlalchemy/py.typed +0 -0
- {duckdb_sqlalchemy-1.5.2.2 → duckdb_sqlalchemy-1.5.4}/duckdb_sqlalchemy/requirements.py +0 -0
- {duckdb_sqlalchemy-1.5.2.2 → duckdb_sqlalchemy-1.5.4}/duckdb_sqlalchemy/tests/__init__.py +0 -0
- {duckdb_sqlalchemy-1.5.2.2 → duckdb_sqlalchemy-1.5.4}/duckdb_sqlalchemy/tests/conftest.py +0 -0
- {duckdb_sqlalchemy-1.5.2.2 → duckdb_sqlalchemy-1.5.4}/duckdb_sqlalchemy/tests/snapshots/test_datatypes/test_interval/schema.sql +0 -0
- {duckdb_sqlalchemy-1.5.2.2 → duckdb_sqlalchemy-1.5.4}/duckdb_sqlalchemy/tests/sqlalchemy_suite/conftest.py +0 -0
- {duckdb_sqlalchemy-1.5.2.2 → duckdb_sqlalchemy-1.5.4}/duckdb_sqlalchemy/tests/sqlalchemy_suite/test_suite.py +0 -0
- {duckdb_sqlalchemy-1.5.2.2 → duckdb_sqlalchemy-1.5.4}/duckdb_sqlalchemy/tests/test_basic.py +0 -0
- {duckdb_sqlalchemy-1.5.2.2 → duckdb_sqlalchemy-1.5.4}/duckdb_sqlalchemy/tests/test_datatypes.py +0 -0
- {duckdb_sqlalchemy-1.5.2.2 → duckdb_sqlalchemy-1.5.4}/duckdb_sqlalchemy/tests/test_integration.py +0 -0
- {duckdb_sqlalchemy-1.5.2.2 → duckdb_sqlalchemy-1.5.4}/duckdb_sqlalchemy/tests/test_pandas.py +0 -0
- {duckdb_sqlalchemy-1.5.2.2 → duckdb_sqlalchemy-1.5.4}/duckdb_sqlalchemy/tests/test_pyarrow.py +0 -0
- {duckdb_sqlalchemy-1.5.2.2 → duckdb_sqlalchemy-1.5.4}/duckdb_sqlalchemy/tests/test_validation.py +0 -0
- {duckdb_sqlalchemy-1.5.2.2 → duckdb_sqlalchemy-1.5.4}/duckdb_sqlalchemy/tests/util.py +0 -0
- {duckdb_sqlalchemy-1.5.2.2 → duckdb_sqlalchemy-1.5.4}/duckdb_sqlalchemy/url.py +0 -0
- {duckdb_sqlalchemy-1.5.2.2 → duckdb_sqlalchemy-1.5.4}/examples/motherduck_attach_modes.py +0 -0
- {duckdb_sqlalchemy-1.5.2.2 → duckdb_sqlalchemy-1.5.4}/examples/motherduck_multi_instance_pool.py +0 -0
- {duckdb_sqlalchemy-1.5.2.2 → duckdb_sqlalchemy-1.5.4}/examples/motherduck_queuepool_high_concurrency.py +0 -0
- {duckdb_sqlalchemy-1.5.2.2 → duckdb_sqlalchemy-1.5.4}/examples/motherduck_read_scaling_per_user.py +0 -0
- {duckdb_sqlalchemy-1.5.2.2 → duckdb_sqlalchemy-1.5.4}/examples/sqlalchemy_example.py +0 -0
- {duckdb_sqlalchemy-1.5.2.2 → duckdb_sqlalchemy-1.5.4}/renovate.json +0 -0
- {duckdb_sqlalchemy-1.5.2.2 → duckdb_sqlalchemy-1.5.4}/test.cfg +0 -0
|
@@ -23,10 +23,10 @@ repos:
|
|
|
23
23
|
language: python
|
|
24
24
|
files: ^duckdb_sqlalchemy/(?!tests/).*\.py$
|
|
25
25
|
additional_dependencies:
|
|
26
|
-
- "ty==0.0.
|
|
26
|
+
- "ty==0.0.54"
|
|
27
27
|
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
28
28
|
# Ruff version.
|
|
29
|
-
rev: 'v0.15.
|
|
29
|
+
rev: 'v0.15.20'
|
|
30
30
|
hooks:
|
|
31
31
|
- id: ruff
|
|
32
32
|
args:
|
|
@@ -8,6 +8,47 @@ preserved from the upstream project for historical context.
|
|
|
8
8
|
|
|
9
9
|
## Unreleased
|
|
10
10
|
|
|
11
|
+
## [1.5.4](https://github.com/leonardovida/duckdb-sqlalchemy/compare/v1.5.3...v1.5.4) (2026-06-26)
|
|
12
|
+
|
|
13
|
+
### Features
|
|
14
|
+
|
|
15
|
+
- expose MotherDuck `md_user_info().c.region` and Flight run `config` columns in the SQLAlchemy table-function helpers
|
|
16
|
+
- document one-off `md_run_flight(config=...)` overrides and selecting effective Flight run config
|
|
17
|
+
- route `motherduck_enable_server_side_temp_tables` through the MotherDuck startup URL parameter bucket
|
|
18
|
+
|
|
19
|
+
### Bug Fixes
|
|
20
|
+
|
|
21
|
+
- restore SQLAlchemy 2.0.0+ compatibility by using a reflection fallback on early 2.0 releases
|
|
22
|
+
- reject empty MotherDuck Flight config keys before compiling Flight helper calls
|
|
23
|
+
- reject invalid MotherDuck Flight config map keys and NUL-containing values before compiling Flight helper calls
|
|
24
|
+
|
|
25
|
+
### Tooling
|
|
26
|
+
|
|
27
|
+
- extend the validated compatibility matrix to DuckDB 1.5.4 and SQLAlchemy 2.0.51
|
|
28
|
+
- bump the local `ty` pin to `0.0.54` and the Ruff pre-commit hook to `0.15.20` after validating the current checks against the latest non-breaking releases
|
|
29
|
+
- refresh the locked development dependency set to the latest non-breaking transitive releases within existing version caps
|
|
30
|
+
|
|
31
|
+
## [1.5.3](https://github.com/leonardovida/duckdb-sqlalchemy/compare/v1.5.2.2...v1.5.3) (2026-06-02)
|
|
32
|
+
|
|
33
|
+
### Features
|
|
34
|
+
|
|
35
|
+
- add `quack_query()` for stateless DuckDB Quack remote queries on DuckDB 1.5.3+
|
|
36
|
+
- add `pragma_storage_info()` for SQLAlchemy access to DuckDB storage metadata
|
|
37
|
+
- add MotherDuck job table-function helpers for job metadata, versions, runs, logs, and job lifecycle operations
|
|
38
|
+
- add MotherDuck Dive table-function helpers for Dives-as-code create, update, fetch, versioning, and cleanup workflows
|
|
39
|
+
|
|
40
|
+
### Bug Fixes
|
|
41
|
+
|
|
42
|
+
- quote validated table-function named parameters so reserved names such as `limit` and `offset` work with SQLAlchemy helpers
|
|
43
|
+
|
|
44
|
+
### Tooling
|
|
45
|
+
|
|
46
|
+
- focus the nox compatibility matrix on active DuckDB release lines while keeping the runtime dependency floor unchanged
|
|
47
|
+
- extend the DuckDB compatibility test matrix to include DuckDB 1.5.3
|
|
48
|
+
- update the SQLAlchemy compatibility matrix to include SQLAlchemy 2.0.50
|
|
49
|
+
- refresh the locked development dependency set to the latest non-breaking releases within existing version caps
|
|
50
|
+
- bump the local `ty` pin to `0.0.38` after validating the current checks against the latest non-breaking release
|
|
51
|
+
|
|
11
52
|
## [1.5.2.2](https://github.com/leonardovida/duckdb-sqlalchemy/compare/v1.5.2.1...v1.5.2.2) (2026-05-11)
|
|
12
53
|
|
|
13
54
|
### Features
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: duckdb-sqlalchemy
|
|
3
|
-
Version: 1.5.
|
|
3
|
+
Version: 1.5.4
|
|
4
4
|
Summary: DuckDB SQLAlchemy dialect for DuckDB and MotherDuck
|
|
5
5
|
Project-URL: Bug Tracker, https://github.com/leonardovida/duckdb-sqlalchemy/issues
|
|
6
6
|
Project-URL: Changelog, https://github.com/leonardovida/duckdb-sqlalchemy/releases
|
|
@@ -27,7 +27,8 @@ Classifier: Topic :: Database :: Front-Ends
|
|
|
27
27
|
Requires-Python: <4,>=3.9
|
|
28
28
|
Requires-Dist: duckdb>=0.5.0
|
|
29
29
|
Requires-Dist: packaging>=21
|
|
30
|
-
Requires-Dist: sqlalchemy>=2.0.
|
|
30
|
+
Requires-Dist: sqlalchemy>=2.0.0; python_version < '3.14'
|
|
31
|
+
Requires-Dist: sqlalchemy>=2.0.45; python_version >= '3.14'
|
|
31
32
|
Provides-Extra: dev
|
|
32
33
|
Requires-Dist: fsspec<2027.0.0,>=2025.2.0; extra == 'dev'
|
|
33
34
|
Requires-Dist: github-action-utils<2.0.0,>=1.1.0; extra == 'dev'
|
|
@@ -46,7 +47,7 @@ Requires-Dist: pytest-snapshot<1.0.0,>=0.9.0; extra == 'dev'
|
|
|
46
47
|
Requires-Dist: pytest<10.0.0,>=8.0.0; extra == 'dev'
|
|
47
48
|
Requires-Dist: pytz>=2024.2; (python_version >= '3.12') and extra == 'dev'
|
|
48
49
|
Requires-Dist: toml<0.11.0,>=0.10.2; extra == 'dev'
|
|
49
|
-
Requires-Dist: ty==0.0.
|
|
50
|
+
Requires-Dist: ty==0.0.54; extra == 'dev'
|
|
50
51
|
Provides-Extra: devtools
|
|
51
52
|
Requires-Dist: nox<2027.0.0,>=2026.4.10; extra == 'devtools'
|
|
52
53
|
Requires-Dist: pdbpp<0.13.0,>=0.11.0; extra == 'devtools'
|
|
@@ -106,8 +107,8 @@ Current direction in this repository:
|
|
|
106
107
|
| Component | Supported versions |
|
|
107
108
|
| --- | --- |
|
|
108
109
|
| Python | 3.9+ |
|
|
109
|
-
| SQLAlchemy | 2.0.45+ (CI-tested: 2.0.
|
|
110
|
-
| DuckDB | 0.5.0+ (CI-tested currently: 1.
|
|
110
|
+
| SQLAlchemy | 2.0.0+ on Python <3.14; 2.0.45+ on Python 3.14+ (CI-tested: 2.0.0, 2.0.51) |
|
|
111
|
+
| DuckDB | 0.5.0+ (CI-tested currently: 1.3.0 to 1.5.4) |
|
|
111
112
|
|
|
112
113
|
## Install
|
|
113
114
|
|
|
@@ -51,8 +51,8 @@ Current direction in this repository:
|
|
|
51
51
|
| Component | Supported versions |
|
|
52
52
|
| --- | --- |
|
|
53
53
|
| Python | 3.9+ |
|
|
54
|
-
| SQLAlchemy | 2.0.45+ (CI-tested: 2.0.
|
|
55
|
-
| DuckDB | 0.5.0+ (CI-tested currently: 1.
|
|
54
|
+
| SQLAlchemy | 2.0.0+ on Python <3.14; 2.0.45+ on Python 3.14+ (CI-tested: 2.0.0, 2.0.51) |
|
|
55
|
+
| DuckDB | 0.5.0+ (CI-tested currently: 1.3.0 to 1.5.4) |
|
|
56
56
|
|
|
57
57
|
## Install
|
|
58
58
|
|
|
@@ -50,7 +50,8 @@ engine = create_engine("duckdb:///analytics.db", connect_args={"read_only": True
|
|
|
50
50
|
- Unknown but syntactically valid keys are forwarded to DuckDB and may fail with
|
|
51
51
|
DuckDB's native "unrecognized configuration parameter" error.
|
|
52
52
|
- MotherDuck path-query options (`attach_mode`, `session_name`, `access_mode`,
|
|
53
|
-
and related keys) are handled
|
|
53
|
+
`motherduck_enable_server_side_temp_tables`, and related keys) are handled
|
|
54
|
+
specially for `md:` URLs. See
|
|
54
55
|
[motherduck.md](motherduck) and [connection-urls.md](connection-urls).
|
|
55
56
|
|
|
56
57
|
## Preload extensions
|
|
@@ -108,6 +108,15 @@ engine = create_engine(f"duckdb:///md:my_db?motherduck_token={escaped}")
|
|
|
108
108
|
|
|
109
109
|
See [motherduck.md](motherduck) for MotherDuck-specific examples and options.
|
|
110
110
|
|
|
111
|
+
## Quack remotes
|
|
112
|
+
|
|
113
|
+
DuckDB 1.5.3 ships Quack as a core extension for remote DuckDB access. Quack is
|
|
114
|
+
normally used from SQL with `ATTACH 'quack:host' AS name (...)` or the
|
|
115
|
+
`quack_query` table function; keep the SQLAlchemy engine connected to a local
|
|
116
|
+
DuckDB database and attach the remote from that session.
|
|
117
|
+
|
|
118
|
+
See [olap.md](olap) for `quack_query` and `ATTACH` examples.
|
|
119
|
+
|
|
111
120
|
## Pool defaults
|
|
112
121
|
|
|
113
122
|
Pooling behavior is described in [configuration.md](configuration)
|
|
@@ -70,6 +70,7 @@ Parameters that are treated as part of the database string:
|
|
|
70
70
|
- `dbinstance_inactivity_ttl` (preferred; `motherduck_dbinstance_inactivity_ttl`
|
|
71
71
|
remains supported but is deprecated)
|
|
72
72
|
- `saas_mode` (`pgendpoint` is supported when you need PG endpoint-compatible routing)
|
|
73
|
+
- `motherduck_enable_server_side_temp_tables`
|
|
73
74
|
- `cache_buster`
|
|
74
75
|
|
|
75
76
|
For backward compatibility the dialect also accepts `session_hint`,
|
|
@@ -50,25 +50,131 @@ parquet = table_function(
|
|
|
50
50
|
stmt = select(parquet.c.event_id, parquet.c.ts)
|
|
51
51
|
```
|
|
52
52
|
|
|
53
|
-
##
|
|
53
|
+
## Storage metadata
|
|
54
54
|
|
|
55
|
-
|
|
56
|
-
The helper names the released columns so they are available through SQLAlchemy:
|
|
55
|
+
Use `pragma_storage_info` to inspect DuckDB table storage through SQLAlchemy:
|
|
57
56
|
|
|
58
57
|
```python
|
|
59
58
|
from sqlalchemy import select
|
|
60
|
-
from duckdb_sqlalchemy import
|
|
59
|
+
from duckdb_sqlalchemy import pragma_storage_info
|
|
60
|
+
|
|
61
|
+
storage = pragma_storage_info("events")
|
|
62
|
+
stmt = select(storage.c.column_name, storage.c.segment_type, storage.c.compression)
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
The helper names DuckDB's released columns by default. On engines that support
|
|
66
|
+
the optional segment-info argument, pass `include_segment_info=True`.
|
|
67
|
+
|
|
68
|
+
## Quack remote queries
|
|
69
|
+
|
|
70
|
+
DuckDB 1.5.3 ships Quack as a core extension. Use `quack_query` for stateless
|
|
71
|
+
remote queries and name the returned columns for SQLAlchemy:
|
|
72
|
+
|
|
73
|
+
```python
|
|
74
|
+
from sqlalchemy import select
|
|
75
|
+
from duckdb_sqlalchemy import quack_query
|
|
76
|
+
|
|
77
|
+
remote = quack_query(
|
|
78
|
+
"quack:localhost",
|
|
79
|
+
"SELECT 42 AS answer",
|
|
80
|
+
columns=["answer"],
|
|
81
|
+
token="MY_QUACK_TOKEN_01234567890ABCDEF",
|
|
82
|
+
)
|
|
83
|
+
stmt = select(remote.c.answer)
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## MotherDuck metadata
|
|
87
|
+
|
|
88
|
+
MotherDuck exposes table functions for account and Dive metadata. The helpers
|
|
89
|
+
name the released columns so they are available through SQLAlchemy:
|
|
90
|
+
|
|
91
|
+
```python
|
|
92
|
+
from sqlalchemy import select
|
|
93
|
+
from duckdb_sqlalchemy import md_access_tokens, md_list_dives, md_user_info
|
|
61
94
|
|
|
62
95
|
user_info = md_user_info()
|
|
63
|
-
|
|
96
|
+
user_stmt = select(
|
|
64
97
|
user_info.c.user_id,
|
|
65
98
|
user_info.c.username,
|
|
66
99
|
user_info.c.org_id,
|
|
67
100
|
user_info.c.org_name,
|
|
68
101
|
user_info.c.org_type,
|
|
102
|
+
user_info.c.region,
|
|
69
103
|
)
|
|
104
|
+
|
|
105
|
+
dives = md_list_dives()
|
|
106
|
+
dives_stmt = select(dives.c.id, dives.c.title, dives.c.required_resources)
|
|
107
|
+
|
|
108
|
+
tokens = md_access_tokens()
|
|
109
|
+
tokens_stmt = select(tokens.c.token_name, tokens.c.token_type, tokens.c.expire_at)
|
|
70
110
|
```
|
|
71
111
|
|
|
112
|
+
## MotherDuck Dives as code
|
|
113
|
+
|
|
114
|
+
Dive helpers expose the SQL functions MotherDuck provides for managing Dives
|
|
115
|
+
from a SQL client or deployment script:
|
|
116
|
+
|
|
117
|
+
```python
|
|
118
|
+
from sqlalchemy import select
|
|
119
|
+
from duckdb_sqlalchemy import (
|
|
120
|
+
md_create_dive,
|
|
121
|
+
md_get_dive,
|
|
122
|
+
md_list_dive_versions,
|
|
123
|
+
md_update_dive_content,
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
created = md_create_dive(
|
|
127
|
+
title="Sales overview",
|
|
128
|
+
content="export default function Dive() { return null }",
|
|
129
|
+
api_version=1,
|
|
130
|
+
required_resources=[{"url": "md:analytics", "alias": "analytics"}],
|
|
131
|
+
)
|
|
132
|
+
create_stmt = select(created.c.id, created.c.version_id)
|
|
133
|
+
|
|
134
|
+
dive = md_get_dive(id="00000000-0000-0000-0000-000000000000")
|
|
135
|
+
dive_stmt = select(dive.c.title, dive.c.content)
|
|
136
|
+
|
|
137
|
+
updated = md_update_dive_content(
|
|
138
|
+
id="00000000-0000-0000-0000-000000000000",
|
|
139
|
+
content="export default function Dive() { return null }",
|
|
140
|
+
)
|
|
141
|
+
update_stmt = select(updated.c.version, updated.c.storage_url)
|
|
142
|
+
|
|
143
|
+
versions = md_list_dive_versions(id="00000000-0000-0000-0000-000000000000")
|
|
144
|
+
versions_stmt = select(versions.c.version, versions.c.created_at)
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
## MotherDuck Flights
|
|
148
|
+
|
|
149
|
+
MotherDuck also exposes preview table functions for Flight metadata. The
|
|
150
|
+
read-only helpers are useful for listing Flights, runs, logs, and versions:
|
|
151
|
+
|
|
152
|
+
```python
|
|
153
|
+
from sqlalchemy import select
|
|
154
|
+
from duckdb_sqlalchemy import md_flight_runs, md_flight_versions, md_flights
|
|
155
|
+
|
|
156
|
+
flights = md_flights(limit=10)
|
|
157
|
+
flights_stmt = select(flights.c.flight_id, flights.c.flight_name, flights.c.status)
|
|
158
|
+
|
|
159
|
+
runs = md_flight_runs(flight_id="00000000-0000-0000-0000-000000000000", limit=10)
|
|
160
|
+
runs_stmt = select(runs.c.run_number, runs.c.status, runs.c.config, runs.c.started_at)
|
|
161
|
+
|
|
162
|
+
versions = md_flight_versions(flight_id="00000000-0000-0000-0000-000000000000")
|
|
163
|
+
versions_stmt = select(versions.c.flight_version, versions.c.requirements_txt)
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
Mutating Flight functions are available as helpers too:
|
|
167
|
+
`md_create_flight`, `md_update_flight`, `md_delete_flight`, `md_run_flight`,
|
|
168
|
+
and `md_cancel_flight_run`. They only execute when the SQLAlchemy statement is
|
|
169
|
+
run. `md_run_flight` accepts a `config` map to override a Flight's config for
|
|
170
|
+
that run only; run result helpers expose the effective `config` column. Config
|
|
171
|
+
map keys must be strings, non-empty, and cannot contain `=` or NUL bytes.
|
|
172
|
+
Config values must be strings or `None`, and cannot contain NUL bytes.
|
|
173
|
+
|
|
174
|
+
The older `md_*job*` helper names remain as deprecated compatibility aliases.
|
|
175
|
+
They compile through the current Flight functions while preserving legacy
|
|
176
|
+
`job_*` column access where possible.
|
|
177
|
+
|
|
72
178
|
## Arrow results
|
|
73
179
|
|
|
74
180
|
For large reads, you can request Arrow tables directly:
|
|
@@ -162,6 +268,18 @@ conn.execute(text("ATTACH 'analytics.duckdb' AS analytics"))
|
|
|
162
268
|
rows = conn.execute(text("SELECT * FROM analytics.events LIMIT 10")).fetchall()
|
|
163
269
|
```
|
|
164
270
|
|
|
271
|
+
Quack remotes can be attached the same way when a Quack server is available:
|
|
272
|
+
|
|
273
|
+
```python
|
|
274
|
+
conn.execute(
|
|
275
|
+
text(
|
|
276
|
+
"ATTACH 'quack:localhost' AS remote_db "
|
|
277
|
+
"(TOKEN 'MY_QUACK_TOKEN_01234567890ABCDEF')"
|
|
278
|
+
)
|
|
279
|
+
)
|
|
280
|
+
rows = conn.execute(text("SELECT * FROM remote_db.events LIMIT 10")).fetchall()
|
|
281
|
+
```
|
|
282
|
+
|
|
165
283
|
## Notes
|
|
166
284
|
|
|
167
285
|
- Column naming for table functions requires SQLAlchemy >= 1.4 (uses `table_valued`).
|