mainsequence 4.2.38__tar.gz → 4.2.39__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.
- {mainsequence-4.2.38/mainsequence.egg-info → mainsequence-4.2.39}/PKG-INFO +1 -1
- {mainsequence-4.2.38 → mainsequence-4.2.39}/agent_scaffold/skills/data_publishing/data_nodes/SKILL.md +6 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/mainsequence/meta_tables/sqlalchemy_contracts.py +73 -1
- {mainsequence-4.2.38 → mainsequence-4.2.39/mainsequence.egg-info}/PKG-INFO +1 -1
- {mainsequence-4.2.38 → mainsequence-4.2.39}/pyproject.toml +1 -1
- {mainsequence-4.2.38 → mainsequence-4.2.39}/tests/test_meta_tables_sqlalchemy_contracts.py +81 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/LICENSE +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/README.md +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/agent_scaffold/AGENTS.md +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/agent_scaffold/skills/a2a_communication/SKILL.md +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/agent_scaffold/skills/application_surfaces/api_surfaces/SKILL.md +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/agent_scaffold/skills/command_center/adapter_from_api/SKILL.md +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/agent_scaffold/skills/command_center/api_mock_prototyping/SKILL.md +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/agent_scaffold/skills/command_center/app_components/SKILL.md +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/agent_scaffold/skills/command_center/connections/SKILL.md +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/agent_scaffold/skills/command_center/workspace_analysis/SKILL.md +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/agent_scaffold/skills/command_center/workspace_builder/SKILL.md +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/agent_scaffold/skills/command_center/workspace_design/SKILL.md +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/agent_scaffold/skills/dashboards/streamlit/SKILL.md +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/agent_scaffold/skills/data_access/exploration/SKILL.md +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/agent_scaffold/skills/data_publishing/meta_tables/SKILL.md +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/agent_scaffold/skills/maintenance/bug_auditor/SKILL.md +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/agent_scaffold/skills/ms-markets/SKILL.md +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/agent_scaffold/skills/platform_operations/access_control_and_sharing/SKILL.md +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/agent_scaffold/skills/platform_operations/orchestration_and_releases/SKILL.md +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/agent_scaffold/skills/project_builder/SKILL.md +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/agent_scaffold/skills/project_to_agent/SKILL.md +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/mainsequence/__init__.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/mainsequence/__main__.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/mainsequence/bootstrap.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/mainsequence/cli/__init__.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/mainsequence/cli/api.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/mainsequence/cli/browser_auth.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/mainsequence/cli/cli.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/mainsequence/cli/config.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/mainsequence/cli/docker_utils.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/mainsequence/cli/doctor.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/mainsequence/cli/local_ops.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/mainsequence/cli/migrations.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/mainsequence/cli/model_filters.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/mainsequence/cli/project_status.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/mainsequence/cli/pydantic_cli.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/mainsequence/cli/sdk_utils.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/mainsequence/cli/ssh_utils.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/mainsequence/cli/ui.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/mainsequence/client/__init__.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/mainsequence/client/agent_runtime_models.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/mainsequence/client/base.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/mainsequence/client/client.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/mainsequence/client/command_center/__init__.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/mainsequence/client/command_center/app_component.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/mainsequence/client/command_center/connections.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/mainsequence/client/command_center/data_models.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/mainsequence/client/command_center/workspace.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/mainsequence/client/command_center/workspace_snapshot.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/mainsequence/client/compute_validation.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/mainsequence/client/data_sources_interfaces/__init__.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/mainsequence/client/data_sources_interfaces/duckdb.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/mainsequence/client/data_sources_interfaces/local_paths.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/mainsequence/client/data_sources_interfaces/sqlite.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/mainsequence/client/dtype_codec.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/mainsequence/client/exceptions.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/mainsequence/client/fastapi/__init__.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/mainsequence/client/fastapi/auth.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/mainsequence/client/metatables/__init__.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/mainsequence/client/metatables/core.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/mainsequence/client/models_foundry.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/mainsequence/client/models_helpers.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/mainsequence/client/models_user.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/mainsequence/client/utils.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/mainsequence/defaults.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/mainsequence/instrumentation/__init__.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/mainsequence/instrumentation/utils.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/mainsequence/logconf.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/mainsequence/meta_tables/__init__.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/mainsequence/meta_tables/__main__.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/mainsequence/meta_tables/compiled_sql/__init__.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/mainsequence/meta_tables/compiled_sql/v1.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/mainsequence/meta_tables/data_nodes/__init__.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/mainsequence/meta_tables/data_nodes/build_operations.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/mainsequence/meta_tables/data_nodes/data_nodes.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/mainsequence/meta_tables/data_nodes/models.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/mainsequence/meta_tables/data_nodes/namespacing.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/mainsequence/meta_tables/data_nodes/persist_managers.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/mainsequence/meta_tables/data_nodes/run_operations.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/mainsequence/meta_tables/data_nodes/utils.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/mainsequence/meta_tables/future_registry.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/mainsequence/meta_tables/hashing.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/mainsequence/meta_tables/migrations.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/mainsequence/meta_tables/pydantic_metadata.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/mainsequence/meta_tables/schema_names.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/mainsequence/runtime_flags.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/mainsequence.egg-info/SOURCES.txt +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/mainsequence.egg-info/dependency_links.txt +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/mainsequence.egg-info/entry_points.txt +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/mainsequence.egg-info/requires.txt +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/mainsequence.egg-info/top_level.txt +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/setup.cfg +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/tests/test_auth_precedence.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/tests/test_build_operations_hashing.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/tests/test_cli.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/tests/test_cli_browser_auth.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/tests/test_cli_migrations.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/tests/test_client.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/tests/test_command_center_app_component_models.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/tests/test_command_center_data_models.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/tests/test_command_center_models.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/tests/test_data_access_mixin_dimension_audit.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/tests/test_data_node_storage_dimension_queries.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/tests/test_data_node_update_flow.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/tests/test_dependency_extras.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/tests/test_duckdb_interface_dimensions.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/tests/test_filter_normalization.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/tests/test_logconf.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/tests/test_meta_table_migrations.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/tests/test_meta_tables_client_models.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/tests/test_models_user_request_bound_auth.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/tests/test_pod_project_resolution.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/tests/test_project_batch_jobs_from_file.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/tests/test_run_configuration.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/tests/test_schema_names.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/tests/test_secret_client_model.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/tests/test_source_table_configuration.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/tests/test_sqlite_interface_dimensions.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/tests/test_update_runner_uid_runtime.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/tests/test_update_statistics.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/tests/test_update_uid_guards.py +0 -0
- {mainsequence-4.2.38 → mainsequence-4.2.39}/tests/test_workspace_snapshot.py +0 -0
|
@@ -191,6 +191,12 @@ MetaTable migration provider and run `mainsequence migrations upgrade --provider
|
|
|
191
191
|
... head`. Do not call `PricesTable.register()` directly and do not rely on
|
|
192
192
|
DataNode construction to register storage tables.
|
|
193
193
|
|
|
194
|
+
`__index_names__` is the full DataNode storage grain. `PlatformTimeIndexMetaData`
|
|
195
|
+
automatically adds a SQLAlchemy unique index over that tuple before Alembic
|
|
196
|
+
autogenerate runs. Do not manually repeat the full grain unique index in
|
|
197
|
+
`__table_args__`; add ordinary SQLAlchemy `Index(...)` entries only for
|
|
198
|
+
additional lookup/performance paths.
|
|
199
|
+
|
|
194
200
|
`PlatformTimeIndexMetaData.register()` remains SDK plumbing for the migration
|
|
195
201
|
workflow. Do not manually attach an existing UID, reconstruct a generic
|
|
196
202
|
`MetaTable`, or use manual bind helpers as an authoring step.
|
{mainsequence-4.2.38 → mainsequence-4.2.39}/mainsequence/meta_tables/sqlalchemy_contracts.py
RENAMED
|
@@ -28,6 +28,7 @@ from mainsequence.client.metatables import (
|
|
|
28
28
|
)
|
|
29
29
|
|
|
30
30
|
from .hashing import build_meta_table_configured_storage_hash
|
|
31
|
+
from .schema_names import schema_index_name
|
|
31
32
|
|
|
32
33
|
DEFAULT_PLATFORM_MANAGED_PROVISIONING = {
|
|
33
34
|
"create_table": True,
|
|
@@ -322,7 +323,9 @@ class PlatformTimeIndexMetaData(PlatformManagedMetaTable):
|
|
|
322
323
|
|
|
323
324
|
from sqlalchemy import Table
|
|
324
325
|
|
|
325
|
-
|
|
326
|
+
table = Table(str(name), metadata, *table_items, **kwargs)
|
|
327
|
+
_ensure_time_index_unique_grain_index(table=table, index_names=index_names)
|
|
328
|
+
return table
|
|
326
329
|
|
|
327
330
|
@classmethod
|
|
328
331
|
def build_registration_request(
|
|
@@ -1391,6 +1394,75 @@ def _validate_time_index_contract(
|
|
|
1391
1394
|
)
|
|
1392
1395
|
|
|
1393
1396
|
|
|
1397
|
+
def _ensure_time_index_unique_grain_index(
|
|
1398
|
+
*,
|
|
1399
|
+
table: Any,
|
|
1400
|
+
index_names: Sequence[str],
|
|
1401
|
+
) -> None:
|
|
1402
|
+
grain_names = [str(name) for name in index_names]
|
|
1403
|
+
if _has_unique_grain_enforcement(table=table, index_names=grain_names):
|
|
1404
|
+
return
|
|
1405
|
+
|
|
1406
|
+
from sqlalchemy import Index
|
|
1407
|
+
|
|
1408
|
+
Index(
|
|
1409
|
+
schema_index_name(_table_name(table), grain_names, unique=True),
|
|
1410
|
+
*(table.c[name] for name in grain_names),
|
|
1411
|
+
unique=True,
|
|
1412
|
+
)
|
|
1413
|
+
|
|
1414
|
+
|
|
1415
|
+
def _has_unique_grain_enforcement(
|
|
1416
|
+
*,
|
|
1417
|
+
table: Any,
|
|
1418
|
+
index_names: Sequence[str],
|
|
1419
|
+
) -> bool:
|
|
1420
|
+
for index in _iter_indexes(table):
|
|
1421
|
+
if bool(getattr(index, "unique", False)) and _grain_columns_match(
|
|
1422
|
+
_index_column_names(index),
|
|
1423
|
+
index_names,
|
|
1424
|
+
):
|
|
1425
|
+
return True
|
|
1426
|
+
|
|
1427
|
+
for constraint in _iter_unique_constraints(table):
|
|
1428
|
+
if _grain_columns_match(_constraint_column_names(constraint), index_names):
|
|
1429
|
+
return True
|
|
1430
|
+
|
|
1431
|
+
return False
|
|
1432
|
+
|
|
1433
|
+
|
|
1434
|
+
def _grain_columns_match(existing_names: Sequence[str], index_names: Sequence[str]) -> bool:
|
|
1435
|
+
existing = [str(name) for name in existing_names]
|
|
1436
|
+
expected = [str(name) for name in index_names]
|
|
1437
|
+
if len(existing) != len(expected):
|
|
1438
|
+
return False
|
|
1439
|
+
return set(existing) == set(expected)
|
|
1440
|
+
|
|
1441
|
+
|
|
1442
|
+
def _index_column_names(index: Any) -> list[str]:
|
|
1443
|
+
return [_storage_item_name(item) for item in _iter_index_items(index)]
|
|
1444
|
+
|
|
1445
|
+
|
|
1446
|
+
def _iter_unique_constraints(table: Any) -> list[Any]:
|
|
1447
|
+
from sqlalchemy import UniqueConstraint
|
|
1448
|
+
|
|
1449
|
+
constraints = getattr(table, "constraints", None)
|
|
1450
|
+
if constraints is None:
|
|
1451
|
+
return []
|
|
1452
|
+
return [
|
|
1453
|
+
constraint
|
|
1454
|
+
for constraint in constraints
|
|
1455
|
+
if isinstance(constraint, UniqueConstraint)
|
|
1456
|
+
]
|
|
1457
|
+
|
|
1458
|
+
|
|
1459
|
+
def _constraint_column_names(constraint: Any) -> list[str]:
|
|
1460
|
+
columns = getattr(constraint, "columns", None)
|
|
1461
|
+
if columns is None:
|
|
1462
|
+
return []
|
|
1463
|
+
return [_storage_item_name(column) for column in columns]
|
|
1464
|
+
|
|
1465
|
+
|
|
1394
1466
|
def _storage_identity_from_parts(
|
|
1395
1467
|
*,
|
|
1396
1468
|
columns: Sequence[Any],
|
|
@@ -22,6 +22,8 @@ from mainsequence.meta_tables import (
|
|
|
22
22
|
external_registered_registration_request_from_sqlalchemy_model,
|
|
23
23
|
platform_managed_migration_registration_context,
|
|
24
24
|
platform_managed_registration_request_from_sqlalchemy_model,
|
|
25
|
+
schema_index_name,
|
|
26
|
+
sqlalchemy_naming_convention,
|
|
25
27
|
table_contract_from_sqlalchemy_model,
|
|
26
28
|
time_indexed_registration_request_from_sqlalchemy_model,
|
|
27
29
|
)
|
|
@@ -1535,6 +1537,85 @@ def test_platform_managed_metatable_preserves_authored_tablename_with_sqlalchemy
|
|
|
1535
1537
|
assert not hasattr(request.table_contract, "foreign_keys")
|
|
1536
1538
|
|
|
1537
1539
|
|
|
1540
|
+
def test_time_index_metadata_generates_unique_grain_index_with_schema_name():
|
|
1541
|
+
pytest.importorskip("sqlalchemy")
|
|
1542
|
+
|
|
1543
|
+
from sqlalchemy import DateTime, Float, MetaData, String
|
|
1544
|
+
from sqlalchemy.orm import DeclarativeBase, mapped_column
|
|
1545
|
+
|
|
1546
|
+
class Base(DeclarativeBase):
|
|
1547
|
+
metadata = MetaData(naming_convention=sqlalchemy_naming_convention())
|
|
1548
|
+
|
|
1549
|
+
class Prices(PlatformTimeIndexMetaData, Base):
|
|
1550
|
+
__tablename__ = "ms_markets__prices__mainsequence_examples"
|
|
1551
|
+
__metatable_namespace__ = "mainsequence.examples"
|
|
1552
|
+
__time_index_name__ = "time_index"
|
|
1553
|
+
__index_names__ = ["time_index", "asset_identifier"]
|
|
1554
|
+
|
|
1555
|
+
time_index: Mapped[datetime.datetime] = mapped_column(
|
|
1556
|
+
DateTime(timezone=True),
|
|
1557
|
+
nullable=False,
|
|
1558
|
+
)
|
|
1559
|
+
asset_identifier: Mapped[str] = mapped_column(String(255), nullable=False)
|
|
1560
|
+
close: Mapped[float] = mapped_column(Float, nullable=True)
|
|
1561
|
+
|
|
1562
|
+
grain_indexes = [
|
|
1563
|
+
index
|
|
1564
|
+
for index in Prices.__table__.indexes
|
|
1565
|
+
if index.unique
|
|
1566
|
+
and [column.name for column in index.columns] == ["time_index", "asset_identifier"]
|
|
1567
|
+
]
|
|
1568
|
+
|
|
1569
|
+
assert len(grain_indexes) == 1
|
|
1570
|
+
assert grain_indexes[0].name == schema_index_name(
|
|
1571
|
+
"ms_markets__prices__mainsequence_examples",
|
|
1572
|
+
["time_index", "asset_identifier"],
|
|
1573
|
+
unique=True,
|
|
1574
|
+
)
|
|
1575
|
+
|
|
1576
|
+
|
|
1577
|
+
def test_time_index_metadata_reuses_existing_unique_grain_constraint():
|
|
1578
|
+
pytest.importorskip("sqlalchemy")
|
|
1579
|
+
|
|
1580
|
+
from sqlalchemy import DateTime, Float, MetaData, String, UniqueConstraint
|
|
1581
|
+
from sqlalchemy.orm import DeclarativeBase, mapped_column
|
|
1582
|
+
|
|
1583
|
+
class Base(DeclarativeBase):
|
|
1584
|
+
metadata = MetaData(naming_convention=sqlalchemy_naming_convention())
|
|
1585
|
+
|
|
1586
|
+
class Prices(PlatformTimeIndexMetaData, Base):
|
|
1587
|
+
__tablename__ = "ms_markets__prices__mainsequence_examples"
|
|
1588
|
+
__table_args__ = (
|
|
1589
|
+
UniqueConstraint(
|
|
1590
|
+
"asset_identifier",
|
|
1591
|
+
"time_index",
|
|
1592
|
+
name="uix_custom_asset_time",
|
|
1593
|
+
),
|
|
1594
|
+
)
|
|
1595
|
+
__metatable_namespace__ = "mainsequence.examples"
|
|
1596
|
+
__time_index_name__ = "time_index"
|
|
1597
|
+
__index_names__ = ["time_index", "asset_identifier"]
|
|
1598
|
+
|
|
1599
|
+
time_index: Mapped[datetime.datetime] = mapped_column(
|
|
1600
|
+
DateTime(timezone=True),
|
|
1601
|
+
nullable=False,
|
|
1602
|
+
)
|
|
1603
|
+
asset_identifier: Mapped[str] = mapped_column(String(255), nullable=False)
|
|
1604
|
+
close: Mapped[float] = mapped_column(Float, nullable=True)
|
|
1605
|
+
|
|
1606
|
+
assert not Prices.__table__.indexes
|
|
1607
|
+
unique_constraints = [
|
|
1608
|
+
constraint
|
|
1609
|
+
for constraint in Prices.__table__.constraints
|
|
1610
|
+
if isinstance(constraint, UniqueConstraint)
|
|
1611
|
+
]
|
|
1612
|
+
assert len(unique_constraints) == 1
|
|
1613
|
+
assert [column.name for column in unique_constraints[0].columns] == [
|
|
1614
|
+
"asset_identifier",
|
|
1615
|
+
"time_index",
|
|
1616
|
+
]
|
|
1617
|
+
|
|
1618
|
+
|
|
1538
1619
|
def test_platform_managed_register_preserves_authored_sqlalchemy_table_name(
|
|
1539
1620
|
monkeypatch,
|
|
1540
1621
|
):
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mainsequence-4.2.38 → mainsequence-4.2.39}/agent_scaffold/skills/a2a_communication/SKILL.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mainsequence-4.2.38 → mainsequence-4.2.39}/agent_scaffold/skills/dashboards/streamlit/SKILL.md
RENAMED
|
File without changes
|
{mainsequence-4.2.38 → mainsequence-4.2.39}/agent_scaffold/skills/data_access/exploration/SKILL.md
RENAMED
|
File without changes
|
|
File without changes
|
{mainsequence-4.2.38 → mainsequence-4.2.39}/agent_scaffold/skills/maintenance/bug_auditor/SKILL.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mainsequence-4.2.38 → mainsequence-4.2.39}/mainsequence/client/command_center/app_component.py
RENAMED
|
File without changes
|
{mainsequence-4.2.38 → mainsequence-4.2.39}/mainsequence/client/command_center/connections.py
RENAMED
|
File without changes
|
{mainsequence-4.2.38 → mainsequence-4.2.39}/mainsequence/client/command_center/data_models.py
RENAMED
|
File without changes
|
|
File without changes
|
{mainsequence-4.2.38 → mainsequence-4.2.39}/mainsequence/client/command_center/workspace_snapshot.py
RENAMED
|
File without changes
|
|
File without changes
|
{mainsequence-4.2.38 → mainsequence-4.2.39}/mainsequence/client/data_sources_interfaces/__init__.py
RENAMED
|
File without changes
|
{mainsequence-4.2.38 → mainsequence-4.2.39}/mainsequence/client/data_sources_interfaces/duckdb.py
RENAMED
|
File without changes
|
|
File without changes
|
{mainsequence-4.2.38 → mainsequence-4.2.39}/mainsequence/client/data_sources_interfaces/sqlite.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mainsequence-4.2.38 → mainsequence-4.2.39}/mainsequence/meta_tables/compiled_sql/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mainsequence-4.2.38 → mainsequence-4.2.39}/mainsequence/meta_tables/data_nodes/build_operations.py
RENAMED
|
File without changes
|
{mainsequence-4.2.38 → mainsequence-4.2.39}/mainsequence/meta_tables/data_nodes/data_nodes.py
RENAMED
|
File without changes
|
|
File without changes
|
{mainsequence-4.2.38 → mainsequence-4.2.39}/mainsequence/meta_tables/data_nodes/namespacing.py
RENAMED
|
File without changes
|
{mainsequence-4.2.38 → mainsequence-4.2.39}/mainsequence/meta_tables/data_nodes/persist_managers.py
RENAMED
|
File without changes
|
{mainsequence-4.2.38 → mainsequence-4.2.39}/mainsequence/meta_tables/data_nodes/run_operations.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mainsequence-4.2.38 → mainsequence-4.2.39}/tests/test_command_center_app_component_models.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mainsequence-4.2.38 → mainsequence-4.2.39}/tests/test_data_node_storage_dimension_queries.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|