bf2343b7e4
Integration Tests - MySQL + Elasticsearch / Detect Changes (push) Waiting to run
Integration Tests - MySQL + Elasticsearch / integration-tests-mysql-elasticsearch (push) Blocked by required conditions
Integration Tests - PostgreSQL + Elasticsearch + Redis / Detect Changes (push) Waiting to run
Integration Tests - PostgreSQL + Elasticsearch + Redis / integration-tests-postgres-elasticsearch-redis (push) Blocked by required conditions
Integration Tests - PostgreSQL + OpenSearch / Detect Changes (push) Waiting to run
Integration Tests - PostgreSQL + OpenSearch / integration-tests-postgres-opensearch (push) Blocked by required conditions
Java Checkstyle / java-checkstyle (push) Waiting to run
Maven Collate Tests / maven-collate-ci (push) Waiting to run
OpenMetadata Service Unit Tests / Detect Changes (push) Waiting to run
OpenMetadata Service Unit Tests / openmetadata-service-unit-tests (push) Blocked by required conditions
OpenMetadata Service Unit Tests / k8s_operator-unit-tests (push) Blocked by required conditions
OpenMetadata Service Unit Tests / openmetadata-service-unit-tests-status (push) Blocked by required conditions
Publish Package to Maven Central Repository / publish-maven-packages (push) Waiting to run
249 lines
11 KiB
SQL
249 lines
11 KiB
SQL
-- Post data migration script for Task System Redesign - OpenMetadata 2.0.0
|
|
-- This script runs after the data migration completes
|
|
|
|
-- =====================================================
|
|
-- NOTE: Suggestion migration (suggestions → task_entity),
|
|
-- thread-based task migration (thread_entity → task_entity),
|
|
-- and legacy system activity migration
|
|
-- (thread_entity generated feed rows → activity_stream)
|
|
-- are handled in Java MigrationUtil because they require
|
|
-- entity-link aware transformation logic.
|
|
-- =====================================================
|
|
|
|
-- =====================================================
|
|
-- PHASE 2D: Migrate announcements from thread_entity → announcement_entity
|
|
-- =====================================================
|
|
|
|
INSERT INTO announcement_entity (id, json, fqnhash)
|
|
SELECT
|
|
json->>'id' AS id,
|
|
jsonb_build_object(
|
|
'id', json->>'id',
|
|
'name', 'announcement-' || (json->>'id'),
|
|
'fullyQualifiedName', 'announcement-' || (json->>'id'),
|
|
'displayName', NULLIF(json->>'message', ''),
|
|
'description', COALESCE(
|
|
json->'announcement'->>'description',
|
|
json->>'message',
|
|
''
|
|
),
|
|
'entityLink', json->>'about',
|
|
'startTime', (json->'announcement'->>'startTime')::bigint,
|
|
'endTime', (json->'announcement'->>'endTime')::bigint,
|
|
'status', CASE
|
|
WHEN (json->'announcement'->>'endTime')::bigint < (extract(epoch from now()) * 1000)::bigint
|
|
THEN 'Expired'
|
|
WHEN (json->'announcement'->>'startTime')::bigint > (extract(epoch from now()) * 1000)::bigint
|
|
THEN 'Scheduled'
|
|
ELSE 'Active'
|
|
END,
|
|
'createdBy', json->>'createdBy',
|
|
'updatedBy', COALESCE(json->>'updatedBy', json->>'createdBy'),
|
|
'createdAt', (json->>'threadTs')::bigint,
|
|
'updatedAt', COALESCE((json->>'updatedAt')::bigint, (json->>'threadTs')::bigint),
|
|
'deleted', false,
|
|
'version', 0.1,
|
|
'reactions', COALESCE(json->'reactions', '[]'::jsonb)
|
|
) AS json,
|
|
md5('announcement-' || (json->>'id')) AS fqnhash
|
|
FROM thread_entity t
|
|
WHERE json->>'type' = 'Announcement'
|
|
AND NOT EXISTS (
|
|
SELECT 1 FROM announcement_entity a WHERE a.id = t.json->>'id'
|
|
)
|
|
ON CONFLICT (id) DO NOTHING;
|
|
|
|
-- =====================================================
|
|
-- PHASE 2E: Rename legacy thread storage to fail stale references
|
|
-- =====================================================
|
|
ALTER TABLE IF EXISTS thread_entity RENAME TO thread_entity_legacy;
|
|
|
|
-- =====================================================
|
|
-- PHASE 2F: Lower workflow trigger polling intervals
|
|
-- =====================================================
|
|
-- Reduce WorkflowEventConsumer poll interval from 10s to 1s.
|
|
-- The legacy 10s default added up to a 10s wait between an entity change and the
|
|
-- workflow-triggered approval task being created. On CI under resource pressure this
|
|
-- often drifted to >2 minutes when combined with Flowable's 60s async job poll. The
|
|
-- new value keeps the trigger pipeline near-real-time.
|
|
UPDATE event_subscription_entity
|
|
SET json = jsonb_set(json, '{pollInterval}', '1'::jsonb)
|
|
WHERE name = 'WorkflowEventConsumer'
|
|
AND (json->>'pollInterval')::int > 1;
|
|
|
|
-- Lower Flowable async/timer job acquisition intervals to keep workflow-driven
|
|
-- task creation responsive. The previous 60s default was a Flowable production setting
|
|
-- carried over verbatim; for OpenMetadata's interactive task UX we want sub-second pickup.
|
|
UPDATE openmetadata_settings
|
|
SET json = jsonb_set(
|
|
jsonb_set(json, '{executorConfiguration,asyncJobAcquisitionInterval}', '1000'::jsonb),
|
|
'{executorConfiguration,timerJobAcquisitionInterval}', '5000'::jsonb)
|
|
WHERE configtype = 'workflowSettings'
|
|
AND json->'executorConfiguration' IS NOT NULL
|
|
AND ((json->'executorConfiguration'->>'asyncJobAcquisitionInterval')::int > 1000
|
|
OR (json->'executorConfiguration'->>'timerJobAcquisitionInterval')::int > 5000);
|
|
|
|
-- pipelineStatuses is a derived field, read on demand from entity_extension_time_series, and is
|
|
-- now an array instead of a single object. Strip any stale single-object value that a GET->PUT
|
|
-- round-trip may have persisted into the stored entity JSON so it cannot break deserialization.
|
|
UPDATE ingestion_pipeline_entity
|
|
SET json = (json::jsonb #- '{pipelineStatuses}')::json
|
|
WHERE json::jsonb #> '{pipelineStatuses}' IS NOT NULL;
|
|
|
|
-- MCP Server and MCP Chat are no longer internal Applications; their enablement now lives in
|
|
-- platform settings (mcpConfiguration). The MCP Chat app was never shipped to customers, so
|
|
-- aiSettings.mcpChat keeps its seeded default shape (no config carry-over).
|
|
|
|
-- MCP Server: keep it disabled if the server app was not installed (mcpConfiguration defaults
|
|
-- to enabled=true, which would otherwise turn it on).
|
|
UPDATE openmetadata_settings
|
|
SET json = jsonb_set(json, '{enabled}', 'false'::jsonb)
|
|
WHERE configtype = 'mcpConfiguration'
|
|
AND NOT EXISTS (SELECT 1 FROM installed_apps ia WHERE ia.name = 'McpApplication');
|
|
|
|
-- Retire the MCP apps (their Java classes and marketplace seeds are removed). Keep the bot users
|
|
-- so the MCP server keeps its principal.
|
|
DELETE FROM entity_relationship er USING installed_apps ia
|
|
WHERE (er.fromId = ia.id OR er.toId = ia.id) AND ia.name IN ('McpApplication', 'McpChatApplication');
|
|
DELETE FROM entity_relationship er USING apps_marketplace ia
|
|
WHERE (er.fromId = ia.id OR er.toId = ia.id) AND ia.name IN ('McpApplication', 'McpChatApplication');
|
|
DELETE FROM installed_apps WHERE name IN ('McpApplication', 'McpChatApplication');
|
|
DELETE FROM apps_marketplace WHERE name IN ('McpApplication', 'McpChatApplication');
|
|
|
|
-- Post data migration script for Task workflow cutover - OpenMetadata 2.0.0 (moved from 2.0.1)
|
|
|
|
-- RdfIndexApp: switch to weekly Saturday cron and full-rebuild every run.
|
|
-- Previous defaults (daily, incremental) were producing unbounded triple growth
|
|
-- because relationship-removal paths weren't fully reconciled. With per-run
|
|
-- CLEAR ALL the dataset always converges to MySQL state; weekly cadence keeps
|
|
-- per-run cost from saturating Fuseki.
|
|
--
|
|
-- Also rewrite `entities` to `["all"]`. Pre-upgrade, an operator could have
|
|
-- narrowed RDF indexing to a subset of entity types; the new recreateIndex=true
|
|
-- semantics issues a CLEAR ALL before indexing, which would otherwise wipe
|
|
-- triples for entity types still in MySQL but missing from the subset list.
|
|
-- Forcing the subset list back to `["all"]` ensures the post-CLEAR-ALL run
|
|
-- repopulates the graph fully; operators can re-narrow after the migration if
|
|
-- they need partial indexing.
|
|
UPDATE installed_apps
|
|
SET json = jsonb_set(
|
|
jsonb_set(
|
|
jsonb_set(json::jsonb, '{appConfiguration,recreateIndex}', 'true'),
|
|
'{appSchedule,cronExpression}',
|
|
'"0 0 * * 6"'
|
|
),
|
|
'{appConfiguration,entities}',
|
|
'["all"]'::jsonb
|
|
)
|
|
WHERE name = 'RdfIndexApp';
|
|
|
|
UPDATE apps_marketplace
|
|
SET json = jsonb_set(json::jsonb, '{appConfiguration,recreateIndex}', 'true')
|
|
WHERE name = 'RdfIndexApp';
|
|
|
|
-- Backfill policyAgentConfig defaults on existing Snowflake services. The schema-level
|
|
-- defaults in snowflakeConnection.json only apply at create-time deserialization; rows
|
|
-- already persisted carry the previous all-false shape and won't pick up the new defaults
|
|
-- without this rewrite. Only fields that are currently false are flipped — any operator-set
|
|
-- true value is preserved.
|
|
UPDATE dbservice_entity
|
|
SET json = jsonb_set(
|
|
json::jsonb,
|
|
'{connection,config,policyAgentConfig,enabled}',
|
|
to_jsonb(true)
|
|
)
|
|
WHERE serviceType = 'Snowflake'
|
|
AND json::jsonb #> '{connection,config,policyAgentConfig,enabled}' = 'false'::jsonb;
|
|
|
|
UPDATE dbservice_entity
|
|
SET json = jsonb_set(
|
|
json::jsonb,
|
|
'{connection,config,policyAgentConfig,supportsFullAccess}',
|
|
to_jsonb(true)
|
|
)
|
|
WHERE serviceType = 'Snowflake'
|
|
AND json::jsonb #> '{connection,config,policyAgentConfig,supportsFullAccess}' = 'false'::jsonb;
|
|
|
|
UPDATE dbservice_entity
|
|
SET json = jsonb_set(
|
|
json::jsonb,
|
|
'{connection,config,policyAgentConfig,supportsMaskedAccess}',
|
|
to_jsonb(true)
|
|
)
|
|
WHERE serviceType = 'Snowflake'
|
|
AND json::jsonb #> '{connection,config,policyAgentConfig,supportsMaskedAccess}' = 'false'::jsonb;
|
|
|
|
-- Services that pre-date the policyAgentConfig field entirely (older rows where the whole
|
|
-- object is missing) — write the full block in one shot. `jsonb_set(..., true)` creates the
|
|
-- key if absent.
|
|
UPDATE dbservice_entity
|
|
SET json = jsonb_set(
|
|
json::jsonb,
|
|
'{connection,config,policyAgentConfig}',
|
|
'{"enabled":true,"supportsColumnAccess":false,"supportsFullAccess":true,"supportsMaskedAccess":true}'::jsonb,
|
|
true
|
|
)
|
|
WHERE serviceType = 'Snowflake'
|
|
AND json::jsonb #> '{connection,config,policyAgentConfig}' IS NULL;
|
|
|
|
-- Databricks: enabled/Full default to true, Column and Masked stay false.
|
|
-- Two guarded flips + one full-object write for legacy rows.
|
|
UPDATE dbservice_entity
|
|
SET json = jsonb_set(
|
|
json::jsonb,
|
|
'{connection,config,policyAgentConfig,enabled}',
|
|
to_jsonb(true)
|
|
)
|
|
WHERE serviceType = 'Databricks'
|
|
AND json::jsonb #> '{connection,config,policyAgentConfig,enabled}' = 'false'::jsonb;
|
|
|
|
UPDATE dbservice_entity
|
|
SET json = jsonb_set(
|
|
json::jsonb,
|
|
'{connection,config,policyAgentConfig,supportsFullAccess}',
|
|
to_jsonb(true)
|
|
)
|
|
WHERE serviceType = 'Databricks'
|
|
AND json::jsonb #> '{connection,config,policyAgentConfig,supportsFullAccess}' = 'false'::jsonb;
|
|
|
|
UPDATE dbservice_entity
|
|
SET json = jsonb_set(
|
|
json::jsonb,
|
|
'{connection,config,policyAgentConfig}',
|
|
'{"enabled":true,"supportsColumnAccess":false,"supportsFullAccess":true,"supportsMaskedAccess":false}'::jsonb,
|
|
true
|
|
)
|
|
WHERE serviceType = 'Databricks'
|
|
AND json::jsonb #> '{connection,config,policyAgentConfig}' IS NULL;
|
|
|
|
-- Corrective heal for instances that already ran the earlier version of this script.
|
|
-- Earlier the Databricks block forced supportsMaskedAccess to true; the intended
|
|
-- default is false. Reset it on every Databricks row that currently has it true.
|
|
UPDATE dbservice_entity
|
|
SET json = jsonb_set(
|
|
json::jsonb,
|
|
'{connection,config,policyAgentConfig,supportsMaskedAccess}',
|
|
to_jsonb(false)
|
|
)
|
|
WHERE serviceType = 'Databricks'
|
|
AND json::jsonb #> '{connection,config,policyAgentConfig,supportsMaskedAccess}' = 'true'::jsonb;
|
|
|
|
-- Postgres no longer declares policyAgentConfig. Earlier this script backfilled the
|
|
-- object onto Postgres rows; remove it so the stored shape matches the schema.
|
|
UPDATE dbservice_entity
|
|
SET json = (json::jsonb #- '{connection,config,policyAgentConfig}')
|
|
WHERE serviceType = 'Postgres'
|
|
AND json::jsonb #> '{connection,config,policyAgentConfig}' IS NOT NULL;
|
|
|
|
-- Remove runtime-only fields (openMetadataServerConnection, privateConfiguration) from stored application data.
|
|
UPDATE installed_apps
|
|
SET json = (json::jsonb - 'openMetadataServerConnection' - 'privateConfiguration')
|
|
WHERE jsonb_exists(json::jsonb, 'openMetadataServerConnection')
|
|
OR jsonb_exists(json::jsonb, 'privateConfiguration');
|
|
|
|
UPDATE entity_extension
|
|
SET json = (json::jsonb - 'openMetadataServerConnection' - 'privateConfiguration')
|
|
WHERE extension LIKE 'app.version.%'
|
|
AND (jsonb_exists(json::jsonb, 'openMetadataServerConnection')
|
|
OR jsonb_exists(json::jsonb, 'privateConfiguration'));
|