Commit Graph

116 Commits

Author SHA1 Message Date
Mike Bridge
be01e4552c feat(versioning): foundation — Continuum capture + parent/child shadow tables + VersionDAO
Adds SQLAlchemy-Continuum as a dependency and wires it as the
canonical capture mechanism for chart, dashboard, and dataset edits.

**Schema** — three Alembic migrations, leaving the chain at one
foundation revision plus one child-shadow revision:

- ``version_transaction`` (renamed from Continuum's default
  ``transaction``; SQL-reserved-word workaround) carries the per-save
  ``user_id`` / ``issued_at`` and is the join target for all shadow
  rows. Auto-incrementing PK; user_id has no FK so import / Celery /
  CLI saves can write rows without an active Flask user.
- Parent shadow tables for the three entity types:
  ``dashboards_version``, ``slices_version``, ``tables_version``.
- Child shadow tables for dataset children + dashboard M2M:
  ``table_columns_version``, ``sql_metrics_version``,
  ``dashboard_slices_version`` (composite PK on the M2M shadow,
  matching the live ``dashboard_slices`` reshape from
  sc-105349-composite-association-pks).

**Models** — ``Dashboard``, ``Slice``, ``SqlaTable`` (and dataset
children ``TableColumn`` / ``SqlMetric``) gain ``__versioned__``
class attributes. The exclude lists carry both M2M relationships
(``owners``, ``roles``, ``dashboards``) and the ``AuditMixin``
columns (``changed_on`` / ``created_on`` / ``changed_by_fk`` /
``created_by_fk`` plus ``last_saved_at`` / ``last_saved_by_fk``
on ``Slice``) so auto-bumped audit fields cannot trigger a
version row on their own (FR-025).

**Plugins** — ``superset/versioning/factory.py`` ships three
Continuum plugins:

- ``VersionTransactionFactory`` renames the transaction table and
  appends the unconditional ``user_id`` column.
- ``VersioningFlaskPlugin`` sources the acting user from Superset's
  ``g.user`` rather than ``flask_login.current_user`` (Superset's
  JWT auth populates ``g.user`` but leaves ``current_user``
  anonymous on API routes).
- ``SkipUnmodifiedPlugin`` filters Continuum's UPDATE operations,
  marking content-equivalent re-saves as ``processed=True`` so they
  don't mint no-op shadow rows (FR-026; see follow-up commits for
  the test). Lives in this commit because it shares the file with
  the other plugins.

**Save-path glue** — a ``before_flush`` baseline listener
(``superset/versioning/baseline.py``) inserts an ``operation_type=0``
shadow row the first time a pre-existing entity is saved, including
the slice-baseline-under-dashboard pattern that gives the dashboard
M2M shadow a row to join against. ``UpdateDashboardCommand`` wraps
its body in ``no_autoflush`` so ``process_tab_diff`` /
``process_native_filter_diff`` don't fire intermediate flushes that
would mint extra version rows. ``DatasetDAO.update_columns`` is
rewritten as a natural-key upsert keyed on ``column_name`` so child
edits flow through ORM events Continuum sees.

**DAO** — ``superset/daos/version.py`` exposes the read API used by
the version endpoints in the next commits:
``current_version_number`` (0-based index, unstable under retention
pruning), ``current_live_transaction_id`` (stable across pruning),
``current_live_version_uuid`` (deterministic UUIDv5), plus
``list_versions`` / ``get_version`` / ``restore_version`` and a
batch ``list_change_records_batch`` for N+1 avoidance.

**Initialization** — ``superset/initialization/__init__.py`` wires
``init_versioning()`` after ``make_versioned()`` runs and the
versioned mappers are configured. Registers the baseline listener
plus the change-record listener (the latter's body lives in the
next commit but the registration site is here because it shares
the init function).

**Tests** — version-capture and version-list integration tests for
each entity type, plus a ``VersionDAO`` unit test suite. Retention
test uses a backdated ``issued_at`` so it can drive
``_prune_old_versions_impl`` synchronously.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 18:42:06 -06:00
Beto Dealmeida
edf4d03218 chore: bump rison to 2.0.0 (#39529) 2026-04-24 15:52:42 -04:00
Richard Fogaca Nienkotter
9c288d66b5 fix(dataset): add missing currency_code_column to DatasetPostSchema (#38853) 2026-03-26 16:58:04 -03:00
Richard Fogaca Nienkotter
5278deaf63 fix(metrics): normalize legacy currency strings (#37455) 2026-02-19 21:25:44 -03:00
Richard Fogaca Nienkotter
f4474b2e3e feat: Dynamic currency (#36416) 2026-01-16 21:58:41 -08:00
Amin Ghadersohi
06a8f4df02 feat(datasets): add datetime format detection to dataset columns (#36150)
Co-authored-by: Claude Code <claude@anthropic.com>
2025-11-25 14:25:24 -08:00
Gabriel Torres Ruiz
0a75bac2a1 fix(error-handling): jinja2 error handling improvements (#34803) 2025-09-02 17:29:07 -04:00
Maxime Beauchemin
4695be5cc5 fix: complete theme management system import/export (#34850)
Co-authored-by: Claude <noreply@anthropic.com>
2025-09-01 15:44:01 -07:00
Vitor Avila
471d9fe737 fix: Add dataset ID to file name on exports (#34782) 2025-08-25 14:54:27 -03:00
Danylo Korostil
31e2143c84 feat(api): Added uuid filed support to dataset, chart, dashboard API (#29573) 2025-08-18 13:05:16 -07:00
Vitor Avila
49689eec6c feat: Enable drilling in embedded (#34319) 2025-08-05 02:23:00 -03:00
Maxime Beauchemin
cb27d5fe8d chore: proper current_app.config proxy usage (#34345)
Co-authored-by: Claude <noreply@anthropic.com>
2025-07-31 19:27:42 -07:00
Beto Dealmeida
b794b192d1 fix: return 422 on invalid SQL (#34303) 2025-07-24 16:40:56 -04:00
Vitor Avila
733f112142 fix: Support metric currency as dict during import (#34080) 2025-07-07 14:00:56 -03:00
Vitor Avila
86e7139245 fix: Dataset currency (#33682) 2025-06-09 22:47:14 -03:00
Vitor Avila
cacf1e06d6 fix: Update dataset's last modified date from column/metric update (#33626) 2025-06-03 12:20:38 -03:00
Vitor Avila
72cd9dffa3 fix: Persist catalog change during dataset update + validation fixes (#33384) 2025-05-08 15:22:25 -03:00
Beto Dealmeida
7ab8534ef6 feat: dataset folders (backend) (#32520)
Co-authored-by: Maxime Beauchemin <maximebeauchemin@gmail.com>
2025-04-11 11:38:08 -07:00
Paul Rhodes
8decc9e45f feat(api): Added uuid to list api calls (#32414) 2025-03-05 16:28:29 -08:00
Evan Rusackas
90651dfe3e fix(dev/ci): pre-commit fixes galore (#32352) 2025-02-24 11:26:45 -07:00
Maxime Beauchemin
e51b95ffa8 chore: enforce more ruff rules (#31447)
Co-authored-by: Elizabeth Thompson <eschutho@gmail.com>
2024-12-18 17:41:34 -08:00
Vitor Avila
e79778ac6d feat(dataset API): Add parameter to optionally render Jinja macros in API response (#30721) 2024-10-30 12:42:27 -03:00
Maxime Beauchemin
a849c29288 chore: enable lint PT009 'use regular assert over self.assert.*' (#30521) 2024-10-07 13:17:27 -07:00
Beto Dealmeida
39209c2b40 fix: handle empty catalog when DB supports them (#29840) 2024-08-13 10:08:43 -04:00
Beto Dealmeida
61c0970968 fix: create permissions on DB import (#29802) 2024-08-06 12:09:21 -04:00
John Bodley
8fb8199a55 chore(dao/command): Add transaction decorator to try to enforce "unit of work" (#24969) 2024-06-28 12:33:56 -07:00
Maxime Beauchemin
7dd28a9003 chore: remove sl_ tables (#28704) 2024-05-29 19:04:37 -07:00
Eyal Ezer
07b2449bd7 refactor: Unify all json.(loads|dumps) usage to utils.json (#28702)
Co-authored-by: Eyal Ezer <eyal.ezer@ge.com>
2024-05-28 14:17:41 -07:00
Beto Dealmeida
f29e1e4c29 feat: catalog support for Databricks native (#28394) 2024-05-09 17:41:15 -04:00
Beto Dealmeida
e6a85c5901 fix: export/import catalogs (#28408) 2024-05-09 14:42:03 -04:00
Daniel Vaz Gaspar
9c065951e7 fix: tests on database, dataset, saved_queries apis (#28397) 2024-05-09 13:43:31 +01:00
John Bodley
467e612533 fix: Remedy logic for UpdateDatasetCommand uniqueness check (#28341) 2024-05-07 06:42:37 -07:00
Maxime Beauchemin
513852b7c3 fix: all_database_access should enable access to all datasets/charts/dashboards (#28205) 2024-05-02 09:25:14 -07:00
Maxime Beauchemin
3ac387bb66 chore: enable ruff's isort equivalent (#28267) 2024-04-30 18:29:49 -07:00
Beto Dealmeida
6cf681df68 feat(SIP-95): new endpoint for table metadata (#28122) 2024-04-25 12:23:49 -04:00
Maxime Beauchemin
2d63722150 chore: set up ruff as a new linter/formatter (#28158) 2024-04-24 17:19:53 -07:00
Beto Dealmeida
99a1601aea refactor: rename get_sqla_engine_with_context (#28012) 2024-04-12 13:31:05 -04:00
John Bodley
481a63da55 chore(tests): Remove ineffectual login (#27149) 2024-04-09 09:52:02 -07:00
Vitor Avila
66bf70172f fix(API): Updating assets via the API should preserve ownership configuration (#27364) 2024-03-06 16:40:41 +00:00
Stepan
2e4f6d3f38 perf(export): export generates unnecessary files content (#26765) 2024-02-21 16:28:38 -07:00
John Bodley
847ed3f5b0 refactor: Ensure Flask framework leverages the Flask-SQLAlchemy session (Phase II) (#26909) 2024-02-14 06:20:15 +13:00
Daniel Vaz Gaspar
5b34395689 fix: chart import validation (#26993) 2024-02-06 12:14:02 +00:00
Daniel Vaz Gaspar
8e19f59dd2 fix: create virtual dataset validation (#26625) 2024-01-17 09:11:15 +00:00
John Bodley
77bd7cf1c6 chore: Reenable SQLite tests which leverage foreign key constraints et al. (#24605) 2024-01-09 06:33:47 +13:00
John Bodley
07bcfa9b5f chore(command): Organize Commands according to SIP-92 (#25850) 2023-11-22 16:55:54 -03:00
Stepan
14c324950a feat(datasource): Checkbox for always filtering main dttm in datasource (#25204)
Co-authored-by: Elizabeth Thompson <eschutho@gmail.com>
2023-09-14 15:57:08 -07:00
Daniel Vaz Gaspar
a9efd4b2e3 fix: dataset safe URL for explore_url (#24686) 2023-08-23 09:31:44 -03:00
Jack Fragassi
4a59a265fb chore: Update DAOs to use singular deletion method instead of bulk (#24894) 2023-08-17 17:00:33 -07:00
Ville Brofeldt
f94dc49fd0 fix(snowflake): opt-in denormalization of column names (#24982) 2023-08-15 16:32:54 -07:00
John Bodley
a156816064 chore(command): Condense delete/bulk-delete operations (#24607)
Co-authored-by: Michael S. Molina <70410625+michael-s-molina@users.noreply.github.com>
2023-07-12 15:45:29 -07:00