Repository navigation
docs: id-first consistency — README read-back + hard_delete, sql-client-spec example #60
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -6,7 +6,7 @@ | |||||||||||||||||||||||||
| [](https://dlthub.com) | ||||||||||||||||||||||||||
| [](LICENSE) | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| Load data into [Hotdata](https://hotdata.dev) managed databases using [dlt](https://dlthub.com) — then read it back through the same pipeline. | ||||||||||||||||||||||||||
| Load data into [Hotdata](https://hotdata.dev) managed databases using [dlt](https://dlthub.com) — then read it back through dlt's standard dataset interface. | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| dlt handles extraction, schema inference, and batching. This package is a **native dlt destination** (`JobClientBase` + `WithStateSync` + `WithSqlClient`) for the Hotdata side: it uploads each batch as Parquet, registers it with your managed database, syncs pipeline state so incremental sources resume, and exposes a server-side read API. | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
|
|
@@ -98,9 +98,17 @@ Managed databases are addressed by id — Hotdata database names are not unique, | |||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| ## Read your data back | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| The **same `pipeline` object** that writes can read, through dlt's standard [dataset interface](https://dlthub.com/docs/general-usage/dataset-access/dataset) — no Hotdata-specific code, no database IDs, no hand-written SQL: | ||||||||||||||||||||||||||
| Reads address the managed database by **id** (names aren't identifiers), so point the reading pipeline at the `database_id` you pinned after the first load (see [Quickstart](#quickstart)). Then dlt's standard [dataset interface](https://dlthub.com/docs/general-usage/dataset-access/dataset) reads it back — no Hotdata-specific code, no hand-written SQL: | ||||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. super nit: (not blocking) Anchored here because it's the nearest diff line — the actual spot is Verify a load, lines 266–277. Those CLI examples still address the database by name ( If the CLI takes an id, reusing the |
||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| ```python | ||||||||||||||||||||||||||
| pipeline = dlt.pipeline( | ||||||||||||||||||||||||||
| pipeline_name="my_pipeline", | ||||||||||||||||||||||||||
| destination=hotdata( | ||||||||||||||||||||||||||
| workspace_id="your_workspace_id", | ||||||||||||||||||||||||||
| database_id="db_abc123", # the id printed on first-run create | ||||||||||||||||||||||||||
| declared_tables=["orders"], | ||||||||||||||||||||||||||
| ), | ||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||
|
Comment on lines
+104
to
+111
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. super nit: (not blocking) This rebinds the same Showing it as the Quickstart config plus
Suggested change
|
||||||||||||||||||||||||||
| ds = pipeline.dataset() | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| ds.table("orders").df() # whole table -> pandas.DataFrame | ||||||||||||||||||||||||||
|
|
@@ -154,7 +162,7 @@ Where `hotdata` stands against the [dlt destination capability spec](https://dlt | |||||||||||||||||||||||||
| |---------------|:-------:|-------| | ||||||||||||||||||||||||||
| | `primary_key` | ✅ | Drives merge/upsert and insert-only de-duplication | | ||||||||||||||||||||||||||
| | `merge_key` | ❌ | Use `primary_key` | | ||||||||||||||||||||||||||
| | `hard_delete` | ❌ | Deletes are not propagated | | ||||||||||||||||||||||||||
| | `hard_delete` | ⚠️ | On `merge` with a `primary_key` (default `upsert` strategy): flagged rows are deleted by key while the rest upsert (boolean hint deletes on `True`, other types on non-null). Otherwise — keyless `merge`, or `insert-only` (even with a key) — flagged rows are dropped from the batch but existing matching rows are *not* deleted, so deletes silently don't propagate | | ||||||||||||||||||||||||||
| | `dedup_sort` | ❌ | | | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| ### Loader file formats | ||||||||||||||||||||||||||
|
|
@@ -260,14 +268,14 @@ If you add a new table later, include it in `declared_tables` on the next run | |||||||||||||||||||||||||
| After a pipeline runs, use the [Hotdata CLI](https://github.com/hotdata-dev/sdk-python) to check that the data landed: | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| ```bash | ||||||||||||||||||||||||||
| # List your managed databases | ||||||||||||||||||||||||||
| # List your managed databases (shows each database's id) | ||||||||||||||||||||||||||
| hotdata databases list | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| # Check that tables are loaded and queryable | ||||||||||||||||||||||||||
| hotdata databases tables list --database sales | ||||||||||||||||||||||||||
| # Address by id (the one printed on first-run create) — names aren't unique | ||||||||||||||||||||||||||
| hotdata databases tables list --database db_abc123 | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| # Query the data | ||||||||||||||||||||||||||
| hotdata query "SELECT * FROM public.orders LIMIT 5" -d sales | ||||||||||||||||||||||||||
| hotdata query "SELECT * FROM public.orders LIMIT 5" -d db_abc123 | ||||||||||||||||||||||||||
|
rohan-hotdata marked this conversation as resolved.
|
||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| ## Demo pipeline | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -456,6 +456,10 @@ info = pipe.run(spans()) | |
| print(info) | ||
|
|
||
| # 2) READ (unlocked by this spec) | ||
| # NOTE (id-first, 0.11.0): reads resolve the managed DB by id. In a single | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. super nit: (not blocking) Anchored on the nearest diff line — the actual spot is
Under id-first that recipe makes every run of the new pipeline create a fresh managed database — same class of stale name-addressing guidance this PR is retiring, and it contradicts the demo section eleven lines above ( Everything else checks out: the |
||
| # process the read needs a database_id — pin the id logged on the first-run | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. super nit: (not blocking) Two more name-based leftovers in this same file that the sweep didn't reach — flagging together since the commit describes a "full claim-audit of docs/":
Either is a one-word fix, or an archival banner on the doc as a whole would cover them along with the example on line 451 that still constructs Separately: the commit message for |
||
| # create above via hotdata(database_id="db_..."). Without it the read raises | ||
| # "no managed database resolved". See README "Read your data back". | ||
|
Comment on lines
+459
to
+462
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: (not blocking) The Acceptance line 9 lines below (line 471) is the claim this note contradicts, and the sweep left it: "step 2 prints DataFrames matching what step 1 wrote — with no database IDs, no The note is correct —
Comment on lines
+459
to
+462
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: (not blocking) This note is correct, but the Acceptance line 9 lines below (line 471) still asserts the opposite: "step 2 prints DataFrames matching what step 1 wrote — with no database IDs, no Leaving the acceptance criterion as-is makes this doc contradict itself within ten lines, which is the exact class of stale claim the PR is auditing for. Suggest striking just the "no database IDs" clause and keeping the rest. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: (not blocking) The note is right, but the Acceptance line nine lines down (line 471–472) still reads "with no database IDs, no |
||
| ds = pipe.dataset() | ||
| print(ds.table("spans").df()) # full table | ||
| print(ds("SELECT model, avg(latency_ms) AS p FROM spans GROUP BY model").df()) # aggregate | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
super nit: (not blocking) Same claim-audit target as the ones this PR fixes, just above the diff: the tagline on line 9 ("then read it back through the same pipeline") and the highlight on line 17 still describe the read as happening through the same pipeline. That holds only when
database_idwas pinned on the writing pipeline — which the Quickstart deliberately doesn't do on first run, which is exactly why this section now constructs a second pipeline. A short qualifier on line 9 would keep the intro and this section consistent.