Migrating from 6.x to 7.0
Main Sequence SDK 7.0 replaces the DataNode vocabulary and wire contract with explicit time-index-table update concepts. This is a hard cut: version 7 has no deprecated aliases, forwarding modules, legacy routes, old CLI commands, or runtime configuration converter.
The current 7.x contract also removes updater-owned execution cadence. There
is no TimeIndexTableUpdateConfiguration, next_update, must_update, or
force_update compatibility surface. Every updater node selected for an
invocation executes; an incremental update may still complete successfully
without producing new rows.
The final 7.x contract also removes the persisted Scheduler runtime wrapper.
The SDK executes the dependency tree directly and correlates the root and
dependency TableUpdateRun records with one internally generated trace_id.
There is no Scheduler, ScheduledUpdateNode, heartbeat, Scheduler endpoint,
or active_update_scheduler_uid request field.
Release boundary
Upgrade the SDK only as part of the coordinated backend cutover. The SDK and backend contracts must be from the same generation.
| SDK | Backend contract | Result |
|---|---|---|
6.0.53 |
Pre-cutover DataNode contract | Required rollback/reference pair |
7.0.0 |
Canonical time-index-table update contract | Required cutover pair |
6.x |
Canonical contract | Unsupported |
7.x |
Pre-cutover contract | Unsupported |
The final source before the cut is the
v6.0.53 tag.
If a project must remain on the old contract temporarily, pin it explicitly:
pip install "mainsequence==6.0.53"
Do not use the pin as a compatibility layer. Move the backend and every participating SDK process to the version 7 contract in the same release window.
Public name changes
| 6.x name | 7.x name | Meaning |
|---|---|---|
DataNode |
TimeIndexTableUpdater |
Executable Python producer behavior |
DataNodeConfiguration |
TimeIndexTableUpdateConfig |
Hashed updater configuration |
APIDataNode |
TimeIndexTableRef |
Read-only reference to a canonical existing table |
DataAccessMixin |
TimeIndexTableAccessMixin |
Shared table-read helpers |
APIPersistManager |
TimeIndexTableReader |
Read access for an existing table |
PersistManager |
TimeIndexTableUpdateManager |
Updater synchronization and persistence |
DataNodeUpdate |
TimeIndexTableUpdate |
Persisted backend update process |
DataNodeUpdateDetails |
TimeIndexTableUpdateDetails |
Operational state for an update process |
LocalTimeSeriesHistoricalUpdate |
TableUpdateRun |
One execution attempt |
RunConfiguration |
Removed | Updater-owned execution scheduling has no replacement in the update contract |
TimeIndexMetaTable remains the table's storage identity and schema contract.
UpdateRunner also keeps its name.
The old mainsequence.meta_tables.data_nodes package no longer exists. Import
authoring types from mainsequence.meta_tables:
from mainsequence.meta_tables import (
TimeIndexTableRef,
TimeIndexTableUpdateConfig,
TimeIndexTableUpdater,
)
Typed API resources remain available from mainsequence.client or
mainsequence.client.metatables under their version 7 names.
Migrate updater classes
Before:
from mainsequence.meta_tables import DataNode, DataNodeConfiguration
class PricesConfig(DataNodeConfiguration):
market: str
class PricesNode(DataNode):
def __init__(self, config: PricesConfig):
super().__init__(config=config, storage_table=PricesTable)
After:
from mainsequence.meta_tables import (
TimeIndexTableUpdateConfig,
TimeIndexTableUpdater,
)
class PricesConfig(TimeIndexTableUpdateConfig):
market: str
class PricesUpdater(TimeIndexTableUpdater):
def __init__(self, config: PricesConfig):
super().__init__(config=config, output_table=PricesTable)
Update framework-facing attributes at the same time:
| 6.x | 7.x |
|---|---|
storage_table |
output_table |
storage_metadata |
output_metadata |
data_node_update |
table_update |
local_persist_manager on an updater |
update_manager |
DATA_NODE_UPDATE_CLASS |
TABLE_UPDATE_CLASS |
Concrete project class names do not have to change. Renaming a class such as
PricesNode changes its import path and therefore its canonical update hash;
coordinate that additional identity change with the backend migration.
Migrate APIDataNode separately
APIDataNode was not an updater despite its name. In version 7 it becomes the
read-only TimeIndexTableRef and can identify only a canonical
TimeIndexMetaTable. It has table-read and statistics operations, but no
run, update, update_hash, updater execution state, or update-tree behavior.
Constructor migration:
| 6.x | 7.x |
|---|---|
APIDataNode.build_from_table_uid(uid) |
TimeIndexTableRef.from_uid(uid) |
APIDataNode.build_from_meta_table(table) |
TimeIndexTableRef.from_meta_table(table) |
APIDataNode.build_from_identifier(identifier) |
TimeIndexTableRef.from_identifier(identifier) |
APIDataNode.build_from_physical_identity(...) |
TimeIndexTableRef.from_physical_identity(...) |
APIDataNode.build_from_local_time_serie(update) |
TimeIndexTableRef.from_table_update(update) |
For example:
prices = TimeIndexTableRef.from_uid(prices_table_uid)
class ReturnsUpdater(TimeIndexTableUpdater):
def dependencies(self):
return {"prices": prices}
The raw APIDataNode(data_source_uid, physical_table_name, ...) constructor and
ambiguous build_from_table_name(...) lookup are removed. Resolve the
TimeIndexMetaTable by UID, identifier, or full physical identity instead.
Code that used api_node.local_persist_manager should use table_ref.reader.
Migrate typed client calls
Replace the resource classes and canonical fields together. Version 7 rejects extra legacy fields during model parsing and before network requests.
Important field and method changes include:
| 6.x | 7.x |
|---|---|
data_node_storage |
output_table |
data_node_storage_uid |
output_table_uid |
time_serie_source_code |
table_updater_source_code |
time_serie_source_code_git_hash |
table_updater_source_code_git_hash |
related_table_uid on update details/runs |
table_update_uid |
create_historical_update(...) |
create_table_update_run(...) |
historical_update_uid |
table_update_run_uid |
CodeRepositoryBranch.get_data_nodes_updates() |
CodeRepositoryBranch.get_time_index_table_updates() |
The canonical collections are:
| Resource | Version 7 collection |
|---|---|
TimeIndexTableUpdate |
time-index-table-updates |
TimeIndexTableUpdateDetails |
time-index-table-update-details |
TableUpdateRun |
table-update-runs |
Old local-time-series routes and old dependency actions are not forwarded.
Custom integrations must use the canonical dependency actions:
POST .../update-dependencies/POST .../table-dependencies/DELETE .../dependencies/
Migrate updater run calls
The updater runtime has one execution mode. The ineffective debug_mode
argument and the internal remote_scheduler escape hatch are removed rather
than retained as deprecated no-ops.
Before:
error, result = updater.run(debug_mode=True)
After:
error, result = updater.run()
The remaining controls are keyword-only:
updater.run(update_tree=False)
updater.run(update_tree=False, update_only_tree=True)
updater.run(override_update_stats=statistics)
Calls passing a positional Boolean, debug_mode, or remote_scheduler fail
immediately. Direct Scheduler client imports and calls must be deleted; there
is no replacement client resource.
Migrate CLI usage
The version 6 aliases are removed:
| 6.x | 7.x |
|---|---|
mainsequence data-node ... |
mainsequence time-index-table ... |
mainsequence data_node ... |
mainsequence time-index-table ... |
mainsequence data-node-storage ... |
mainsequence time-index-table ... |
mainsequence data_node_storage ... |
mainsequence time-index-table ... |
mainsequence code-repository data-node-updates list |
mainsequence code-repository time-index-table-updates list |
Expect configuration and hash rotation
Version 7 accepts only updater configuration schema version 2:
{
"configuration_schema_version": 2,
"table_updater_class_import_path": {
"module": "pipelines.prices",
"qualname": "PricesUpdater"
}
}
The legacy time_series_class_import_path key, old dependency marker booleans,
old dependency kind values, and configuration without version 2 are
invalid. Canonical dependency values serialize as either:
{
"kind": "table_update",
"update_hash": "...",
"output_table_uid": "..."
}
or:
{
"kind": "time_index_table_ref",
"time_index_meta_table_uid": "...",
"data_source_uid": "..."
}
The schema and marker changes intentionally rotate updater hashes. The backend
must transform stored build configurations, hashes, dependency edges, and
related identities offline before the canonical application starts. The SDK
does not read or convert legacy payloads. Backend implementers should use the
shared exact cases in
tests/fixtures/time_index_table_update_hash_v2_golden.json
as the conversion contract.
Application migration checklist
- Confirm the backend cutover and offline data migration are ready.
- Pin or lock
mainsequence==7.0.0for every participating process. - Replace the imports, base classes, properties, typed resources, and CLI commands listed above.
- Rewrite every
APIDataNodeuse as a canonical read-onlyTimeIndexTableRef; do not make it an updater subclass. - Remove hand-authored or cached legacy configuration payloads.
- Review concrete updater-class renames because import paths affect hashes.
- Run the project's tests and exercise updater construction, dependency traversal, reads, and one complete update lifecycle against the cutover backend.
- Deploy all SDK processes in the coordinated release window.
Use these searches as a final review, adjusting excluded historical or generated directories for the project:
rg -n 'mainsequence\.meta_tables\.data_nodes|\b(DataNode|DataNodeConfiguration|APIDataNode)\b' .
rg -n '\b(storage_table|storage_metadata|data_node_update|data_node_storage)\b' .
rg -n 'time_series_class_import_path|local-time-series|data-node-updates' .
Any live application match must be migrated. Historical release notes may keep the old names when they describe an earlier version.