mainsequence-metatable 0.1.0__tar.gz → 0.1.2.dev3__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_metatable-0.1.0/mainsequence_metatable.egg-info → mainsequence_metatable-0.1.2.dev3}/PKG-INFO +2 -2
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/app/bootstrap.py +34 -19
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/app/main.py +2 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/app/routes/table_import.py +25 -2
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/backends/contracts.py +2 -1
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/backends/relation_tables.py +161 -42
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/contracts/relation_import.py +14 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/integrations/local_workspace.py +4 -5
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/operations/import_relations.py +81 -47
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/docs/adr/api/0001-unified-api-storage-and-local-sqlite.md +31 -16
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/docs/adr/api/0010-import-external-tables-and-views.md +42 -9
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/docs/api/data-sources.md +1 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/docs/api/openapi.json +138 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/docs/api/reference.md +1 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/docs/api/tables-and-migrations.md +14 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/docs/client/register-existing-tables.md +22 -6
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/docs/concepts/architecture.md +1 -1
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/docs/contributing/database-backends.md +5 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/docs/contributing/testing.md +6 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/docs/operations/catalog-migrations.md +1 -1
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/docs/operations/configuration.md +1 -1
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/docs/operations/local-runtime.md +21 -6
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3/mainsequence_metatable.egg-info}/PKG-INFO +2 -2
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/mainsequence_metatable.egg-info/SOURCES.txt +1 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/mainsequence_metatable.egg-info/requires.txt +1 -1
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/pyproject.toml +2 -2
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/auth/test_runtime_bootstrap.py +79 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/auth/test_runtime_selection.py +51 -1
- mainsequence_metatable-0.1.2.dev3/tests/contracts/test_relation_batching.py +205 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/database_backend/test_relation_import.py +55 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/e2e/test_sqlite_runtime.py +5 -4
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/integrations/test_local_data_sources.py +18 -8
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/uv.lock +2 -2
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/.agents/skills/client/metatables-meta-tables/SKILL.md +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/.agents/skills/client/metatables-migrations/SKILL.md +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/.agents/skills/client/metatables-time-index-table-updates/SKILL.md +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/.mainsequence/workflows/metatables-api.yaml +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/LICENSE +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/MANIFEST.in +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/README.md +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/alembic.ini +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/__init__.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/app/__init__.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/app/auth/__init__.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/app/auth/boundary.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/app/auth/caller_assertions.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/app/auth/local_actor.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/app/configuration.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/app/credential_admin.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/app/development.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/app/development_client.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/app/platform_cache.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/app/routes/__init__.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/app/routes/application_migrations.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/app/routes/column_search.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/app/routes/contract_validation.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/app/routes/data_sources.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/app/routes/managed_finalize.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/app/routes/migration_connection.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/app/routes/namespaces.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/app/routes/run_logs.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/app/routes/runtime_context.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/app/routes/schema_graph.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/app/routes/security.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/app/routes/table_cascade.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/app/routes/table_crud.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/app/routes/table_delete.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/app/routes/table_filter.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/app/routes/table_introspection.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/app/routes/table_patch.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/app/routes/table_registration.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/app/routes/table_response.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/app/routes/table_search_document.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/app/routes/table_sql.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/app/routes/table_update_pipeline.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/app/routes/time_index_delete.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/app/routes/time_index_reads.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/app/routes/time_index_stats.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/app/routes/update_batch.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/app/routes/update_chunk_insert.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/app/routes/update_constants.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/app/routes/update_crud.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/app/routes/update_details.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/app/routes/update_graph.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/app/routes/update_index_statistics.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/app/routes/update_registration.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/app/routes/update_runs.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/app/routes/update_statistics.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/app/runtime.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/app/runtime_control.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/app/source_passwords.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/app/source_registrations.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/__init__.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/backends/__init__.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/backends/access.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/backends/adapters/__init__.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/backends/adapters/maintenance/__init__.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/backends/adapters/maintenance/postgresql.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/backends/adapters/maintenance/runtime.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/backends/adapters/maintenance/temporal.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/backends/adapters/maintenance/timescaledb.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/backends/adapters/maintenance/validation.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/backends/adapters/postgresql_cascade_delete.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/backends/adapters/postgresql_connection.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/backends/adapters/postgresql_introspection.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/backends/adapters/postgresql_table_delete.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/backends/adapters/postgresql_tables.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/backends/adapters/postgresql_time_index.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/backends/adapters/postgresql_time_index_delete.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/backends/adapters/postgresql_time_index_queries.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/backends/adapters/postgresql_time_index_stats.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/backends/adapters/postgresql_time_index_write.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/backends/adapters/source_validation.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/backends/adapters/sqlite_connection.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/backends/adapters/sqlite_introspection.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/backends/adapters/table_cursor.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/backends/catalog.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/backends/catalog_ddl.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/backends/catalog_types.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/backends/hosted.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/backends/hosted_access.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/backends/native.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/backends/operations.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/backends/postgresql_access.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/backends/registry.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/backends/relational.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/backends/restricted_sql.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/backends/sqlite_access.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/contracts/__init__.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/contracts/storage_layouts.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/contracts/table_contracts.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/contracts/values.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/domain/__init__.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/domain/catalog_rules.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/domain/data_source_rules.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/domain/index_statistics.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/domain/label_rules.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/domain/permission_rules.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/domain/update_constants.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/integrations/__init__.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/integrations/catalog_data_sources.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/integrations/credential_keys.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/integrations/credential_store.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/integrations/data_source_provider.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/integrations/local_credentials.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/integrations/platform_principals.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/integrations/run_logs.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/integrations/runtime_binding.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/integrations/runtime_data_sources.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/integrations/source_validation.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/migrations/__init__.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/migrations/env.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/migrations/script.py.mako +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/migrations/versions/0001_initial.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/migrations/versions/0002_security_model.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/migrations/versions/0003_run_log_capture.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/migrations/versions/0004_historical_run_graphs.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/migrations/versions/0005_database_access.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/migrations/versions/0006_local_credentials.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/migrations/versions/0007_external_relation_names.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/migrations/versions/__init__.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/operations/__init__.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/operations/bootstrap_migrations.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/operations/catalog_schema.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/operations/create_table.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/operations/finalize_managed.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/operations/introspect_table.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/operations/read_time_index.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/operations/register_catalog.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/operations/search_documents.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/persistence/__init__.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/persistence/cascade.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/persistence/catalog.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/persistence/database.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/persistence/grants.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/persistence/labels.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/persistence/locking.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/persistence/models.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/persistence/physical_operations.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/persistence/projections.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/persistence/run_graphs.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/persistence/schema_graph.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/persistence/sqlite_types.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/persistence/table_body_filter.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/persistence/table_queries.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/persistence/table_response.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/persistence/update_graph.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/persistence/update_pipeline.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/persistence/updates.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/presentation/data_source_summary.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/metatables/__init__.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/metatables/configuration.yaml +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/metatables/main.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/compose.database-tests.yml +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/docs/adr/api/0002-application-administration-and-table-ownership.md +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/docs/adr/api/0004-approved-application-migrations.md +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/docs/adr/api/0005-run-logs-and-local-file-capture.md +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/docs/adr/api/0006-historical-run-graphs.md +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/docs/adr/api/0007-database-enforced-table-access.md +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/docs/adr/api/0007-database-roles-and-privileges.svg +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/docs/adr/api/0007-query-enforcement-path.svg +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/docs/adr/api/0008-mysql-mssql-table-workflows.md +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/docs/adr/api/0009-shared-credential-store.md +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/docs/adr/client/0003-api-endpoint-resolution.md +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/docs/adr/index.md +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/docs/api/authentication-and-errors.md +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/docs/api/overview.md +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/docs/api/time-index-and-updates.md +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/docs/assets/branding/metatables.svg +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/docs/client/build-an-updater.md +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/docs/client/define-and-migrate-tables.md +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/docs/client/installation-and-connection.md +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/docs/client/local-storage.md +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/docs/client/query-and-mutate.md +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/docs/client/quickstart.md +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/docs/client/read-existing-time-index-tables.md +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/docs/client/tutorial.md +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/docs/concepts/data-sources.md +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/docs/concepts/identity-and-scope.md +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/docs/concepts/permissions-namespaces-labels.md +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/docs/concepts/runs-and-execution-graphs.md +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/docs/concepts/table-contracts-and-lifecycle.md +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/docs/concepts/time-index-tables-and-updates.md +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/docs/contributing/architecture-and-boundaries.md +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/docs/contributing/documentation.md +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/docs/contributing/releasing.md +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/docs/examples/README.md +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/docs/examples/__init__.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/docs/examples/data_sources/README.md +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/docs/examples/data_sources/mssql.json +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/docs/examples/data_sources/mysql.json +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/docs/examples/data_sources/postgresql.json +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/docs/examples/data_sources/register.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/docs/examples/external_table.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/docs/examples/query.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/docs/examples/quickstart.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/docs/examples/reader.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/docs/examples/scripts/__init__.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/docs/examples/scripts/setup_metatables.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/docs/examples/tables.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/docs/examples/tutorial/README.md +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/docs/examples/tutorial/__init__.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/docs/examples/tutorial/__main__.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/docs/examples/tutorial/data/README.md +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/docs/examples/tutorial/data/yahoo_spy_qqq_iwm_2026-06-15_2026-07-17.csv +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/docs/examples/tutorial/frames.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/docs/examples/tutorial/migrations/__init__.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/docs/examples/tutorial/migrations/env.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/docs/examples/tutorial/migrations/registry.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/docs/examples/tutorial/migrations/script.py.mako +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/docs/examples/tutorial/migrations/versions/__init__.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/docs/examples/tutorial/migrations/versions/metatables_market_tutorial/0001_create_market_tutorial_tables.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/docs/examples/tutorial/migrations/versions/metatables_market_tutorial/__init__.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/docs/examples/tutorial/operations.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/docs/examples/tutorial/tables.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/docs/examples/tutorial/updaters.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/docs/examples/updater.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/docs/index.md +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/docs/operations/hosted-runtime.md +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/docs/operations/recovery-and-observability.md +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/docs/operations/run-history.md +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/docs/operations/run-logs.md +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/docs/reference/capabilities.md +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/docs/reference/cli.md +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/docs/reference/python.md +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/docs/security/index.md +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/docs/security/ownership-and-sharing.md +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/docs/security/permissions.md +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/examples/README.md +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/examples/__init__.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/examples/data_sources/README.md +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/examples/data_sources/mssql.json +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/examples/data_sources/mysql.json +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/examples/data_sources/postgresql.json +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/examples/data_sources/register.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/examples/external_table.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/examples/query.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/examples/quickstart.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/examples/reader.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/examples/scripts/__init__.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/examples/scripts/setup_metatables.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/examples/tables.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/examples/tutorial/README.md +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/examples/tutorial/__init__.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/examples/tutorial/__main__.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/examples/tutorial/data/README.md +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/examples/tutorial/data/yahoo_spy_qqq_iwm_2026-06-15_2026-07-17.csv +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/examples/tutorial/frames.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/examples/tutorial/migrations/__init__.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/examples/tutorial/migrations/env.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/examples/tutorial/migrations/registry.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/examples/tutorial/migrations/script.py.mako +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/examples/tutorial/migrations/versions/__init__.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/examples/tutorial/migrations/versions/metatables_market_tutorial/0001_create_market_tutorial_tables.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/examples/tutorial/migrations/versions/metatables_market_tutorial/__init__.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/examples/tutorial/operations.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/examples/tutorial/tables.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/examples/tutorial/updaters.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/examples/updater.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/mainsequence_metatable.egg-info/dependency_links.txt +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/mainsequence_metatable.egg-info/entry_points.txt +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/mainsequence_metatable.egg-info/top_level.txt +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/mkdocs.yml +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/scripts/__init__.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/scripts/build_package.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/scripts/build_reference.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/scripts/check_boundaries.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/scripts/check_client_api_coverage.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/scripts/check_distribution_sources.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/scripts/check_docs.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/scripts/check_examples_debug.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/scripts/check_project.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/scripts/dev_release_version.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/scripts/test_databases.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/scripts/test_postgresql.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/setup.cfg +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/src/metatables/__init__.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/src/metatables/_skill_bundle.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/src/metatables/cli/__init__.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/src/metatables/cli/app.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/src/metatables/cli/filters.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/src/metatables/cli/migrations.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/src/metatables/cli/skills.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/src/metatables/compiled_sql/__init__.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/src/metatables/compiled_sql/mssql.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/src/metatables/compiled_sql/v1.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/src/metatables/dtype_codec.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/src/metatables/endpoint.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/src/metatables/future_registry.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/src/metatables/hashing.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/src/metatables/instrumentation.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/src/metatables/local_run_logs.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/src/metatables/log_contract.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/src/metatables/migrations/__init__.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/src/metatables/migrations/alembic.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/src/metatables/migrations/env.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/src/metatables/migrations/provider.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/src/metatables/migrations/registry.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/src/metatables/migrations/scaffold.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/src/metatables/migrations/templates/__init__.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/src/metatables/migrations/templates/env.py.mako +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/src/metatables/migrations/templates/script.py.mako +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/src/metatables/migrations/tls.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/src/metatables/models.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/src/metatables/pydantic_metadata.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/src/metatables/run_logging.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/src/metatables/runtime_context.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/src/metatables/runtime_contract.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/src/metatables/schema_names.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/src/metatables/sdk_compat.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/src/metatables/sqlalchemy_contracts.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/src/metatables/time_index_table_refs.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/src/metatables/transport.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/src/metatables/update_configuration_contract.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/src/metatables/updaters/__init__.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/src/metatables/updaters/configuration.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/src/metatables/updaters/dependencies.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/src/metatables/updaters/managers.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/src/metatables/updaters/namespacing.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/src/metatables/updaters/runner.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/src/metatables/updaters/updaters.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/src/metatables/updaters/utils.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/auth/test_caller_assertions.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/auth/test_data_source_identity.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/auth/test_development_client.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/auth/test_hosted_environment_target.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/auth/test_local_mode.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/auth/test_platform_fact_cache.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/auth/test_runtime_scaffold.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/auth/test_runtime_storage_binding.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/auth/test_source_passwords.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/catalog/test_catalog_foundation.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/catalog/test_contract_projection.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/catalog/test_database_config.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/catalog/test_index_statistics.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/catalog/test_migration.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/conftest.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/contracts/capabilities.json +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/contracts/client_signatures.json +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/contracts/database_operations.json +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/contracts/test_relation_import.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/contracts/test_storage_layouts.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/contracts/test_table_contracts.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/database_backend/Dockerfile +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/database_backend/Dockerfile.dockerignore +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/database_backend/__init__.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/database_backend/conftest.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/database_backend/provider/__init__.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/database_backend/provider/env.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/database_backend/provider/versions/0001_measurement.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/database_backend/test_api_contract.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/database_backend/test_application_migration.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/database_backend/test_bootstrap_recovery.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/database_backend/test_catalog_contract.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/database_backend/test_credential_catalog.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/database_backend/test_physical_contract.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/database_backend/test_runtime_bootstrap.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/database_backend/test_sql_security.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/database_backend/test_update_client.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/database_operations/test_physical_operations.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/database_operations/test_postgresql_operations.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/database_operations/test_runtime_and_temporal.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/documentation/test_project_checks.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/e2e/test_api_endpoint.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/e2e/test_catalog_outage.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/e2e/test_client_api_contract.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/e2e/test_client_api_coverage.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/e2e/test_client_migration_scaffold.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/e2e/test_client_migration_tls.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/e2e/test_client_package.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/e2e/test_client_signatures.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/e2e/test_client_value_behaviors.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/e2e/test_data_source_registry.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/e2e/test_local_actor_client_api.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/e2e/test_managed_finalize_client_api.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/e2e/test_namespaces_admin_http.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/e2e/test_public_imports.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/e2e/test_remaining_client_routes.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/e2e/test_run_graphs.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/e2e/test_run_logs.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/e2e/test_runtime_transition.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/e2e/test_sdk_local_startup.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/e2e/test_table_delete_client_api.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/e2e/test_table_filter_client_api.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/e2e/test_table_introspection_client_api.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/e2e/test_table_patch_client_api.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/e2e/test_table_search_document_api.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/e2e/test_table_stats_api.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/e2e/test_table_update_pipeline.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/e2e/test_table_updates_http.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/e2e/test_time_index_delete_client_api.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/e2e/test_time_index_reads_client_api.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/e2e/test_update_batch_client_api.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/e2e/test_update_chunk_insert_client_api.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/e2e/test_update_dependency_priority_client_api.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/e2e/test_update_index_statistics_client_api.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/e2e/test_update_registration_client_api.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/examples/test_documented_examples.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/examples/test_postgresql_examples.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/examples/test_setup_launch.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/examples/test_tutorial.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/integrations/test_credential_store.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/integrations/test_data_source_rules.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/integrations/test_local_run_logs.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/integrations/test_postgresql_connection.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/integrations/test_postgresql_sql.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/integrations/test_postgresql_tables.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/integrations/test_postgresql_time_index_queries.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/integrations/test_source_validation.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/integrations/test_sqlite_operations.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/labels/test_labels.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/operations/test_create_table_operation.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/operations/test_create_table_postgres.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/operations/test_physical_operation_journal.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/operations/test_register_catalog.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/operations/test_search_documents.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/packaging/test_client_skills.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/packaging/test_dev_release_version.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/packaging/test_distribution_sources.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/packaging/test_editable_build.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/packaging/test_installed_distribution.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/permissions/test_governed_sql_scope.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/permissions/test_local_actor_membership.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/permissions/test_migration_boundary.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/permissions/test_namespace_grants.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/permissions/test_security_api.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/permissions/test_table_body_filter.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/permissions/test_table_grants.py +0 -0
- {mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/tests/permissions/test_table_queries.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mainsequence-metatable
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.2.dev3
|
|
4
4
|
Summary: Main Sequence MetaTables Python client and standalone API
|
|
5
5
|
Author-email: Main Sequence GmbH <dev@main-sequence.io>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -32,7 +32,7 @@ Requires-Dist: pyodbc<6,>=5
|
|
|
32
32
|
Requires-Dist: pydantic<3,>=2.11
|
|
33
33
|
Requires-Dist: pyyaml
|
|
34
34
|
Requires-Dist: requests>=2.33.0
|
|
35
|
-
Requires-Dist: sqlalchemy<3,>=2
|
|
35
|
+
Requires-Dist: sqlalchemy<3,>=2.1
|
|
36
36
|
Requires-Dist: psycopg[binary]<4,>=3.2
|
|
37
37
|
Requires-Dist: structlog
|
|
38
38
|
Requires-Dist: tqdm<5,>=4.66
|
|
@@ -33,7 +33,12 @@ from api.backend.persistence.database import (
|
|
|
33
33
|
migration_config,
|
|
34
34
|
upgrade_catalog,
|
|
35
35
|
)
|
|
36
|
-
from api.backend.persistence.models import
|
|
36
|
+
from api.backend.persistence.models import (
|
|
37
|
+
Base,
|
|
38
|
+
DataSource,
|
|
39
|
+
MetaTable,
|
|
40
|
+
PhysicalOperation,
|
|
41
|
+
)
|
|
37
42
|
from metatables.runtime_contract import RuntimeBootstrapDescriptor
|
|
38
43
|
|
|
39
44
|
VERSION_TABLE = "metatables_catalog_version"
|
|
@@ -77,7 +82,8 @@ class RuntimeBootstrap:
|
|
|
77
82
|
self.uid = None
|
|
78
83
|
self.selected_source_uid = None
|
|
79
84
|
self.saved_path = (config.configuration_path or Path.cwd() / "configuration.yaml").resolve().parent / ".local/runtime-data-sources.json"
|
|
80
|
-
self.selection_key =
|
|
85
|
+
self.selection_key = "local" if self.workspace else "hosted"
|
|
86
|
+
self.save_local_selection = False
|
|
81
87
|
|
|
82
88
|
def descriptor(self, user_uid, *, is_admin=False):
|
|
83
89
|
can_configure = is_admin
|
|
@@ -136,8 +142,20 @@ class RuntimeBootstrap:
|
|
|
136
142
|
if self.selection_key == "hosted":
|
|
137
143
|
self.selected_source_uid = saved.get("hosted_source_uid")
|
|
138
144
|
return saved[self.selection_key]
|
|
145
|
+
if self.workspace:
|
|
146
|
+
# Adopt an unambiguous old file intact, never copy catalog rows.
|
|
147
|
+
legacy = {value["configuration"]["path"]: value for value in saved.values()
|
|
148
|
+
if isinstance(value, dict) and value.get("class_type") == "sqlite"
|
|
149
|
+
and isinstance(value.get("configuration", {}).get("path"), str)}
|
|
150
|
+
if len(legacy) == 1:
|
|
151
|
+
self.save_local_selection = True
|
|
152
|
+
return next(iter(legacy.values()))
|
|
153
|
+
if legacy:
|
|
154
|
+
self.error = "Multiple legacy local databases are saved. Choose the existing local runtime file in Settings; no database has been replaced."
|
|
155
|
+
return None
|
|
139
156
|
except (OSError, ValueError):
|
|
140
157
|
self.error = "Saved runtime selection cannot be read. Configure the DataSource again."
|
|
158
|
+
return None
|
|
141
159
|
if self.workspace:
|
|
142
160
|
return dict(display_name=self.workspace.data_source.display_name, class_type="sqlite",
|
|
143
161
|
configuration={"path": str(self.workspace.tables_path)})
|
|
@@ -164,7 +182,15 @@ class RuntimeBootstrap:
|
|
|
164
182
|
path = path.resolve()
|
|
165
183
|
marker = _read_marker(path.with_name(path.name + ".metatables-scope.json"))
|
|
166
184
|
if marker and marker != {"workspace_uid": str(self.workspace.uid), "purpose": "runtime"}:
|
|
167
|
-
|
|
185
|
+
# Preserve the selected legacy file's runtime/source IDs and log
|
|
186
|
+
# ownership. Git branches no longer define storage identity.
|
|
187
|
+
saved = json.loads(self.saved_path.read_text()) if self.saved_path.exists() else {}
|
|
188
|
+
known = saved.get("local") or saved.get(marker.get("workspace_uid"))
|
|
189
|
+
if (marker.get("purpose") != "runtime" or not isinstance(known, dict)
|
|
190
|
+
or known.get("class_type") != "sqlite"
|
|
191
|
+
or known.get("configuration", {}).get("path") != str(path)):
|
|
192
|
+
raise BootstrapError("This file belongs to another workspace or the retired two-file layout.")
|
|
193
|
+
self.workspace = replace(self.workspace, uid=UUID(marker["workspace_uid"]))
|
|
168
194
|
self.workspace = replace(self.workspace, database_path=path)
|
|
169
195
|
values["configuration"] = {"path": str(path)}
|
|
170
196
|
else:
|
|
@@ -298,21 +324,6 @@ class RuntimeBootstrap:
|
|
|
298
324
|
raise BootstrapError("The existing runtime registration cannot be replaced by this configuration or caller.")
|
|
299
325
|
from api.backend.backends.registry import backend_for
|
|
300
326
|
session.flush()
|
|
301
|
-
if self.workspace:
|
|
302
|
-
# Existing local candidate metadata is materialized into
|
|
303
|
-
# the catalog, retaining UIDs. Credentials require the
|
|
304
|
-
# explicit import or password replacement procedure.
|
|
305
|
-
from api.app.source_registrations import read_registry
|
|
306
|
-
saved = read_registry(self.saved_path.with_name("runtime-source-candidates.json"))
|
|
307
|
-
for candidate in saved.values():
|
|
308
|
-
if candidate.get("class_type") not in {"postgresql", "timescale_db", "mysql", "mssql"}:
|
|
309
|
-
continue
|
|
310
|
-
candidate_uid = UUID(candidate["uid"])
|
|
311
|
-
if session.get(DataSource, candidate_uid) is None:
|
|
312
|
-
session.add(DataSource(uid=candidate_uid, created_by_user_uid=user_uid,
|
|
313
|
-
display_name=candidate["display_name"], class_type=candidate["class_type"],
|
|
314
|
-
configuration=candidate["configuration"], storage_access_mode=candidate["storage_access_mode"],
|
|
315
|
-
status=candidate["status"], is_default=False, is_runtime=False))
|
|
316
327
|
backend_for(replace(self.backend.source, uid=row.uid)).access.initialize(session)
|
|
317
328
|
credentials = bind_store(self.credential_store, session, user_uid)
|
|
318
329
|
if hasattr(credentials, "initialize"):
|
|
@@ -341,6 +352,9 @@ class RuntimeBootstrap:
|
|
|
341
352
|
self.saved_path.parent.mkdir(parents=True, exist_ok=True, mode=0o700)
|
|
342
353
|
# Public configuration only: password and TLS material remain Secret references.
|
|
343
354
|
saved = json.loads(self.saved_path.read_text()) if self.saved_path.exists() else {}
|
|
355
|
+
if self.workspace:
|
|
356
|
+
saved = {key: value for key, value in saved.items()
|
|
357
|
+
if not (isinstance(value, dict) and value.get("class_type") == "sqlite")}
|
|
344
358
|
saved[self.selection_key] = self.candidate
|
|
345
359
|
if self.selection_key == "hosted":
|
|
346
360
|
if self.selected_source_uid:
|
|
@@ -413,9 +427,10 @@ class RuntimeBootstrap:
|
|
|
413
427
|
if self.workspace:
|
|
414
428
|
_bind_file(Path(self.candidate["configuration"]["path"]),
|
|
415
429
|
workspace_uid=self.workspace.uid, purpose="runtime")
|
|
416
|
-
if persist:
|
|
430
|
+
if persist or self.save_local_selection:
|
|
417
431
|
try:
|
|
418
432
|
self.persist_selection()
|
|
433
|
+
self.save_local_selection = False
|
|
419
434
|
except Exception:
|
|
420
435
|
raise BootstrapError("Unable to save runtime selection. The database is initialized but was not activated.") from None
|
|
421
436
|
binding = RuntimeStorageBinding(catalog_url=str(self.engine.url), workspace=self.workspace,
|
|
@@ -25,6 +25,7 @@ from api.app.routes.table_crud import router as table_crud_router
|
|
|
25
25
|
from api.app.routes.table_delete import router as table_delete_router
|
|
26
26
|
from api.app.routes.table_filter import router as table_filter_router
|
|
27
27
|
from api.app.routes.table_import import router as table_import_router
|
|
28
|
+
from api.app.routes.table_import import source_router as source_relations_router
|
|
28
29
|
from api.app.routes.table_introspection import router as table_introspection_router
|
|
29
30
|
from api.app.routes.table_patch import router as table_patch_router
|
|
30
31
|
from api.app.routes.table_registration import router as table_registration_router
|
|
@@ -180,6 +181,7 @@ def create_app(config: RuntimeConfig | None = None) -> FastAPI:
|
|
|
180
181
|
service.include_router(migration_connection_router)
|
|
181
182
|
service.include_router(application_migrations_router)
|
|
182
183
|
service.include_router(table_import_router)
|
|
184
|
+
service.include_router(source_relations_router)
|
|
183
185
|
service.include_router(table_registration_router)
|
|
184
186
|
service.include_router(table_cascade_router)
|
|
185
187
|
for inherited in (contract_validation_router, column_search_router, schema_graph_router,
|
{mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/app/routes/table_import.py
RENAMED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
from uuid import UUID
|
|
4
4
|
|
|
5
|
-
from fastapi import APIRouter, Depends, HTTPException
|
|
5
|
+
from fastapi import APIRouter, Depends, HTTPException, Query
|
|
6
6
|
from sqlalchemy.exc import SQLAlchemyError
|
|
7
7
|
from sqlalchemy.orm import Session
|
|
8
8
|
|
|
@@ -15,14 +15,21 @@ from api.backend.contracts.relation_import import (
|
|
|
15
15
|
ImportRelations,
|
|
16
16
|
ImportResult,
|
|
17
17
|
ReadRelation,
|
|
18
|
+
RelationDiscovery,
|
|
18
19
|
RelationRows,
|
|
19
20
|
)
|
|
20
21
|
from api.backend.domain.data_source_rules import DataSourceAdmissionError
|
|
21
22
|
from api.backend.domain.permission_rules import TrustedActorFacts
|
|
23
|
+
from api.backend.integrations.credential_store import CredentialStoreError
|
|
22
24
|
from api.backend.integrations.runtime_data_sources import DataSourceIntegrationError
|
|
23
|
-
from api.backend.operations.import_relations import
|
|
25
|
+
from api.backend.operations.import_relations import (
|
|
26
|
+
discover_import_relations,
|
|
27
|
+
import_relations,
|
|
28
|
+
read_relation,
|
|
29
|
+
)
|
|
24
30
|
|
|
25
31
|
router = APIRouter(prefix="/meta-tables", tags=["MetaTables"])
|
|
32
|
+
source_router = APIRouter(prefix="/data-sources", tags=["DataSources"])
|
|
26
33
|
|
|
27
34
|
|
|
28
35
|
def invoke(session, operation):
|
|
@@ -31,6 +38,9 @@ def invoke(session, operation):
|
|
|
31
38
|
except RelationError as exc:
|
|
32
39
|
session.rollback()
|
|
33
40
|
raise HTTPException(exc.status, {"code": exc.code}) from None
|
|
41
|
+
except CredentialStoreError as exc:
|
|
42
|
+
session.rollback()
|
|
43
|
+
raise HTTPException(503, {"code": exc.code, "detail": exc.message}) from None
|
|
34
44
|
except (DataSourceIntegrationError, DataSourceAdmissionError, SQLExecutionError) as exc:
|
|
35
45
|
session.rollback()
|
|
36
46
|
raise HTTPException(getattr(exc, "status_code", 409), {"code": exc.code}) from None
|
|
@@ -45,6 +55,19 @@ def invoke(session, operation):
|
|
|
45
55
|
raise HTTPException(422, {"code": "invalid_relation_contract"}) from None
|
|
46
56
|
|
|
47
57
|
|
|
58
|
+
@source_router.get("/{source_uid}/relations/", response_model=RelationDiscovery)
|
|
59
|
+
def discover_source_relations(
|
|
60
|
+
source_uid: UUID,
|
|
61
|
+
physical_schema: str | None = Query(default=None, max_length=128),
|
|
62
|
+
session: Session = Depends(catalog_session),
|
|
63
|
+
actor: TrustedActorFacts = Depends(trusted_actor_facts),
|
|
64
|
+
sources=Depends(data_source_provider),
|
|
65
|
+
):
|
|
66
|
+
return invoke(session, lambda: discover_import_relations(
|
|
67
|
+
session, sources, actor, source_uid, physical_schema
|
|
68
|
+
))
|
|
69
|
+
|
|
70
|
+
|
|
48
71
|
@router.post("/import-from-data-source/", response_model=ImportResult)
|
|
49
72
|
def import_source(
|
|
50
73
|
payload: ImportRelations,
|
{mainsequence_metatable-0.1.0 → mainsequence_metatable-0.1.2.dev3}/api/backend/backends/contracts.py
RENAMED
|
@@ -35,7 +35,8 @@ class OperationContext:
|
|
|
35
35
|
class TableBackend(Protocol):
|
|
36
36
|
def context_for_catalog(self, session, context): ...
|
|
37
37
|
def discover_relations(self, *, schema=None, context, external=False): ...
|
|
38
|
-
def
|
|
38
|
+
def inspect_relations(self, *, schema=None, context, external=False): ...
|
|
39
|
+
def introspect_relations(self, *, schema, names, context, external=False, check_read=True): ...
|
|
39
40
|
def read_relation(self, *, table, selection, admission, context): ...
|
|
40
41
|
|
|
41
42
|
def statistics(
|
|
@@ -14,6 +14,7 @@ from time import monotonic
|
|
|
14
14
|
from uuid import UUID
|
|
15
15
|
|
|
16
16
|
import sqlalchemy as sa
|
|
17
|
+
from sqlalchemy.engine.reflection import ObjectKind, ObjectScope
|
|
17
18
|
from sqlalchemy.exc import SQLAlchemyError
|
|
18
19
|
|
|
19
20
|
from api.backend.backends.restricted_sql import json_value
|
|
@@ -42,6 +43,12 @@ class RelationContext:
|
|
|
42
43
|
return value
|
|
43
44
|
|
|
44
45
|
|
|
46
|
+
@dataclass
|
|
47
|
+
class RelationSnapshotBatch:
|
|
48
|
+
snapshots: dict[str, dict]
|
|
49
|
+
failures: dict[str, RelationError]
|
|
50
|
+
|
|
51
|
+
|
|
45
52
|
def protected(schema, name):
|
|
46
53
|
from api.backend.persistence.models import Base
|
|
47
54
|
|
|
@@ -215,29 +222,59 @@ class RelationAdapter:
|
|
|
215
222
|
inspector = sa.inspect(connection)
|
|
216
223
|
return inspector.has_table("credential_vault", schema=inspector.default_schema_name)
|
|
217
224
|
|
|
218
|
-
def discover(self, connection, schema):
|
|
225
|
+
def discover(self, connection, schema, inspector=None):
|
|
219
226
|
schema = self.physical_schema(schema)
|
|
220
|
-
inspector = sa.inspect(connection)
|
|
227
|
+
inspector = inspector if inspector is not None else sa.inspect(connection)
|
|
221
228
|
relations = {name: "table" for name in inspector.get_table_names(schema=schema)}
|
|
222
229
|
relations.update({name: "view" for name in inspector.get_view_names(schema=schema)})
|
|
223
230
|
return {name: kind for name, kind in relations.items() if not protected(schema, name)}
|
|
224
231
|
|
|
225
|
-
def
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
232
|
+
def unique_constraints(self, inspector, options):
|
|
233
|
+
return inspector.get_multi_unique_constraints(**options)
|
|
234
|
+
|
|
235
|
+
def inspect_many(self, inspector, schema, names, visible):
|
|
236
|
+
"""Reflect a selection on one Inspector, retaining its dialect metadata cache.
|
|
237
|
+
|
|
238
|
+
PostgreSQL and MSSQL use native bulk catalog queries. Dialects that
|
|
239
|
+
reflect individual definitions (MySQL/SQLite) reuse the same connection
|
|
240
|
+
and cached definitions across columns, keys and indexes.
|
|
241
|
+
"""
|
|
242
|
+
if not names:
|
|
243
|
+
return RelationSnapshotBatch({}, {})
|
|
244
|
+
physical_schema = self.physical_schema(schema)
|
|
245
|
+
unreflectable = {}
|
|
246
|
+
options = dict(
|
|
247
|
+
schema=physical_schema, filter_names=names, kind=ObjectKind.ANY,
|
|
248
|
+
scope=ObjectScope.ANY, unreflectable=unreflectable,
|
|
240
249
|
)
|
|
250
|
+
# Names have already been admitted by discovery. ANY avoids redundant
|
|
251
|
+
# name discovery in SQLAlchemy's per-object reflection fallback.
|
|
252
|
+
columns = inspector.get_multi_columns(**options)
|
|
253
|
+
table_names = [name for name in names if visible[name] == "table"]
|
|
254
|
+
keys, indexes, unique, foreign_keys = {}, {}, {}, {}
|
|
255
|
+
if table_names:
|
|
256
|
+
options = {**options, "filter_names": table_names}
|
|
257
|
+
keys = inspector.get_multi_pk_constraint(**options)
|
|
258
|
+
indexes = inspector.get_multi_indexes(**options)
|
|
259
|
+
unique = self.unique_constraints(inspector, options)
|
|
260
|
+
foreign_keys = inspector.get_multi_foreign_keys(**options)
|
|
261
|
+
result = RelationSnapshotBatch({}, {})
|
|
262
|
+
for name in names:
|
|
263
|
+
key = (physical_schema, name)
|
|
264
|
+
if key in unreflectable or not columns.get(key):
|
|
265
|
+
result.failures[name] = RelationError("relation_metadata_unavailable")
|
|
266
|
+
continue
|
|
267
|
+
try:
|
|
268
|
+
result.snapshots[name] = self.snapshot(
|
|
269
|
+
inspector.bind, schema, name, visible[name], columns[key],
|
|
270
|
+
keys.get(key, {}).get("constrained_columns") or [],
|
|
271
|
+
indexes.get(key, []), unique.get(key, []), foreign_keys.get(key, []),
|
|
272
|
+
)
|
|
273
|
+
except RelationError as exc:
|
|
274
|
+
result.failures[name] = exc
|
|
275
|
+
return result
|
|
276
|
+
|
|
277
|
+
def snapshot(self, connection, schema, name, kind, columns, keys, indexes, unique, foreign_keys):
|
|
241
278
|
by_name = {}
|
|
242
279
|
for index in [*indexes, *[{**item, "unique": True} for item in unique]]:
|
|
243
280
|
names = index.get("column_names") or []
|
|
@@ -249,9 +286,8 @@ class RelationAdapter:
|
|
|
249
286
|
for item in by_name.values()
|
|
250
287
|
if item["unique"] and len(item["columns"]) == 1
|
|
251
288
|
}
|
|
252
|
-
foreign_keys = inspector.get_foreign_keys(name, schema=schema) if kind == "table" else []
|
|
253
289
|
result = dict(
|
|
254
|
-
schema_name=
|
|
290
|
+
schema_name=schema or "",
|
|
255
291
|
table_name=name,
|
|
256
292
|
relation_kind=kind,
|
|
257
293
|
dialect=connection.dialect.name,
|
|
@@ -272,7 +308,7 @@ class RelationAdapter:
|
|
|
272
308
|
dict(
|
|
273
309
|
name=f.get("name") or "fk_" + "_".join(f["constrained_columns"]),
|
|
274
310
|
source_columns=f["constrained_columns"],
|
|
275
|
-
target_schema=f.get("referred_schema") or
|
|
311
|
+
target_schema=f.get("referred_schema") or schema or "",
|
|
276
312
|
target_table=f["referred_table"],
|
|
277
313
|
target_columns=f["referred_columns"],
|
|
278
314
|
on_delete=(f.get("options", {}).get("ondelete") or "no action").lower(),
|
|
@@ -280,13 +316,25 @@ class RelationAdapter:
|
|
|
280
316
|
for f in foreign_keys
|
|
281
317
|
],
|
|
282
318
|
)
|
|
283
|
-
# A bounded probe tests database read access, including view dependencies.
|
|
284
|
-
table = sa.table(name, *[sa.column(c["name"]) for c in columns], schema=schema)
|
|
285
|
-
rows = connection.execute(sa.select(table).limit(1)).mappings().all()
|
|
286
|
-
for row in rows:
|
|
287
|
-
wire_value(dict(row))
|
|
288
319
|
return bounded_json(result, 262144, "relation_metadata_limit_exceeded")
|
|
289
320
|
|
|
321
|
+
def validate_reads(self, connection, snapshots):
|
|
322
|
+
# Each zero-row subquery binds every selected column for permission and
|
|
323
|
+
# view validation. A constant outer projection makes different physical
|
|
324
|
+
# shapes compatible in one UNION ALL, without reading application rows.
|
|
325
|
+
statements = []
|
|
326
|
+
for snapshot in snapshots:
|
|
327
|
+
table = sa.table(
|
|
328
|
+
snapshot["table_name"],
|
|
329
|
+
*[sa.column(c["name"]) for c in snapshot["columns"]],
|
|
330
|
+
schema=self.physical_schema(snapshot["schema_name"]),
|
|
331
|
+
)
|
|
332
|
+
statements.append(
|
|
333
|
+
sa.select(sa.literal_column("1")).select_from(sa.select(table).limit(0).subquery())
|
|
334
|
+
)
|
|
335
|
+
with connection.execute(sa.union_all(*statements)):
|
|
336
|
+
pass
|
|
337
|
+
|
|
290
338
|
def relation_identity(self, connection, identity, table):
|
|
291
339
|
return identity
|
|
292
340
|
|
|
@@ -499,6 +547,11 @@ class MySQLRelations(RelationAdapter):
|
|
|
499
547
|
|
|
500
548
|
|
|
501
549
|
class MSSQLRelations(RelationAdapter):
|
|
550
|
+
def unique_constraints(self, inspector, options):
|
|
551
|
+
# SQL Server's reflected indexes already include unique constraints.
|
|
552
|
+
# Its unique-constraint Inspector method is not implemented.
|
|
553
|
+
return {}
|
|
554
|
+
|
|
502
555
|
def database_identity(self, connection):
|
|
503
556
|
return (
|
|
504
557
|
"mssql",
|
|
@@ -550,6 +603,77 @@ class MSSQLRelations(RelationAdapter):
|
|
|
550
603
|
pending.append((target_schema, target))
|
|
551
604
|
|
|
552
605
|
|
|
606
|
+
class RelationInspection:
|
|
607
|
+
"""One read connection and one discovery result for a selection and FK closure."""
|
|
608
|
+
|
|
609
|
+
def __init__(self, adapter, connection, schema, context, external):
|
|
610
|
+
self.adapter, self.connection = adapter, connection
|
|
611
|
+
self.schema, self.context, self.external = schema, context, external
|
|
612
|
+
self.inspector = sa.inspect(connection)
|
|
613
|
+
self.visible = adapter.discover(connection, schema, self.inspector)
|
|
614
|
+
|
|
615
|
+
def inspect(self, names, *, check_read=True):
|
|
616
|
+
result = RelationSnapshotBatch({}, {})
|
|
617
|
+
selected = []
|
|
618
|
+
for name in dict.fromkeys(names):
|
|
619
|
+
if name not in self.visible:
|
|
620
|
+
result.failures[name] = RelationError("relation_not_found", 404)
|
|
621
|
+
else:
|
|
622
|
+
selected.append(name)
|
|
623
|
+
self.context.remaining()
|
|
624
|
+
reflected = self.adapter.inspect_many(
|
|
625
|
+
self.inspector, self.schema, selected, self.visible
|
|
626
|
+
)
|
|
627
|
+
result.failures.update(reflected.failures)
|
|
628
|
+
for name, snapshot in reflected.snapshots.items():
|
|
629
|
+
self.context.remaining()
|
|
630
|
+
try:
|
|
631
|
+
if not self.external and self.visible[name] == "view":
|
|
632
|
+
self.adapter.validate_runtime_view(self.connection, self.schema, name)
|
|
633
|
+
except RelationError as exc:
|
|
634
|
+
if exc.status == 504:
|
|
635
|
+
raise
|
|
636
|
+
result.failures[name] = exc
|
|
637
|
+
except SQLAlchemyError:
|
|
638
|
+
self.context.remaining()
|
|
639
|
+
if self.connection.invalidated:
|
|
640
|
+
raise RelationError("relation_access_failed", 503) from None
|
|
641
|
+
self.reset_transaction()
|
|
642
|
+
result.failures[name] = RelationError("relation_access_failed", 503)
|
|
643
|
+
else:
|
|
644
|
+
result.snapshots[name] = snapshot
|
|
645
|
+
if check_read and result.snapshots:
|
|
646
|
+
failures = self.check_reads(list(result.snapshots.values()))
|
|
647
|
+
result.failures.update(failures)
|
|
648
|
+
for name in failures:
|
|
649
|
+
del result.snapshots[name]
|
|
650
|
+
self.context.remaining()
|
|
651
|
+
return result
|
|
652
|
+
|
|
653
|
+
def reset_transaction(self):
|
|
654
|
+
# A denied SELECT may abort a PostgreSQL transaction. Restore the
|
|
655
|
+
# read-only settings before checking the remaining relations.
|
|
656
|
+
self.connection.rollback()
|
|
657
|
+
self.adapter.configure(self.connection, self.context)
|
|
658
|
+
|
|
659
|
+
def check_reads(self, snapshots):
|
|
660
|
+
self.context.remaining()
|
|
661
|
+
try:
|
|
662
|
+
self.adapter.validate_reads(self.connection, snapshots)
|
|
663
|
+
except SQLAlchemyError:
|
|
664
|
+
self.context.remaining()
|
|
665
|
+
if self.connection.invalidated:
|
|
666
|
+
raise RelationError("relation_access_failed", 503) from None
|
|
667
|
+
self.reset_transaction()
|
|
668
|
+
if len(snapshots) == 1:
|
|
669
|
+
return {snapshots[0]["table_name"]: RelationError("relation_access_failed", 503)}
|
|
670
|
+
# Isolate denied/broken relations only on failure. The normal path
|
|
671
|
+
# checks the entire batch with one round trip.
|
|
672
|
+
middle = len(snapshots) // 2
|
|
673
|
+
return self.check_reads(snapshots[:middle]) | self.check_reads(snapshots[middle:])
|
|
674
|
+
return {}
|
|
675
|
+
|
|
676
|
+
|
|
553
677
|
class RelationTables:
|
|
554
678
|
@property
|
|
555
679
|
def relations(self):
|
|
@@ -568,29 +692,24 @@ class RelationTables:
|
|
|
568
692
|
return replace(context, runtime_database_identity=adapter.database_identity(connection))
|
|
569
693
|
|
|
570
694
|
def discover_relations(self, *, schema=None, context, external=False):
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
with adapter.connection(context) as connection:
|
|
574
|
-
if external:
|
|
575
|
-
adapter.require_external(connection, context)
|
|
576
|
-
return schema or "", adapter.discover(connection, schema)
|
|
695
|
+
with self.inspect_relations(schema=schema, context=context, external=external) as reader:
|
|
696
|
+
return reader.schema or "", reader.visible
|
|
577
697
|
|
|
578
|
-
|
|
698
|
+
@contextmanager
|
|
699
|
+
def inspect_relations(self, *, schema=None, context, external=False):
|
|
579
700
|
adapter = self.relations
|
|
580
701
|
schema = adapter.schema(schema)
|
|
581
702
|
with adapter.connection(context) as connection:
|
|
582
703
|
if external:
|
|
583
704
|
adapter.require_external(connection, context)
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
results[name] = adapter.inspect(connection, schema, name, visible[name])
|
|
593
|
-
return results
|
|
705
|
+
yield RelationInspection(adapter, connection, schema, context, external)
|
|
706
|
+
|
|
707
|
+
def introspect_relations(self, *, schema, names, context, external=False, check_read=True):
|
|
708
|
+
with self.inspect_relations(schema=schema, context=context, external=external) as reader:
|
|
709
|
+
batch = reader.inspect(names, check_read=check_read)
|
|
710
|
+
if batch.failures:
|
|
711
|
+
raise next(iter(batch.failures.values()))
|
|
712
|
+
return batch.snapshots
|
|
594
713
|
|
|
595
714
|
def read_relation(self, *, table, selection, admission, context):
|
|
596
715
|
adapter = self.relations
|
|
@@ -6,6 +6,20 @@ from uuid import UUID
|
|
|
6
6
|
from pydantic import BaseModel, ConfigDict, Field, field_validator
|
|
7
7
|
|
|
8
8
|
|
|
9
|
+
class DiscoveredRelation(BaseModel):
|
|
10
|
+
name: str
|
|
11
|
+
relation_kind: Literal["table", "view"]
|
|
12
|
+
meta_table_uid: UUID | None
|
|
13
|
+
importable: bool
|
|
14
|
+
blocked_reason: str | None = None
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class RelationDiscovery(BaseModel):
|
|
18
|
+
data_source_uid: UUID
|
|
19
|
+
physical_schema: str
|
|
20
|
+
relations: list[DiscoveredRelation]
|
|
21
|
+
|
|
22
|
+
|
|
9
23
|
class ImportRelations(BaseModel):
|
|
10
24
|
model_config = ConfigDict(extra="forbid")
|
|
11
25
|
data_source_uid: UUID
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"""API-owned local
|
|
1
|
+
"""One API-owned local runtime per checkout, independent of Git branches."""
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
@@ -47,7 +47,7 @@ class LocalWorkspace:
|
|
|
47
47
|
status="AVAILABLE",
|
|
48
48
|
storage_access_mode='read_write',
|
|
49
49
|
connection=SQLiteConnectionSettings(path=self.tables_path),
|
|
50
|
-
display_name=
|
|
50
|
+
display_name="Local MetaTables",
|
|
51
51
|
)
|
|
52
52
|
|
|
53
53
|
|
|
@@ -72,7 +72,7 @@ def _file_path(value: str, *, directory: Path) -> Path:
|
|
|
72
72
|
|
|
73
73
|
|
|
74
74
|
def _bind_file(path: Path, *, workspace_uid: UUID, purpose: str) -> None:
|
|
75
|
-
"""
|
|
75
|
+
"""Bind a runtime file without changing its persistent storage identity."""
|
|
76
76
|
path.parent.mkdir(parents=True, exist_ok=True, mode=0o700)
|
|
77
77
|
marker = path.with_name(path.name + ".metatables-scope.json")
|
|
78
78
|
payload = {"workspace_uid": str(workspace_uid), "purpose": purpose}
|
|
@@ -107,7 +107,7 @@ def _read_marker(path: Path):
|
|
|
107
107
|
|
|
108
108
|
|
|
109
109
|
def bind_workspace_files(workspace: LocalWorkspace) -> None:
|
|
110
|
-
"""Explicit initialization binds the single runtime file
|
|
110
|
+
"""Explicit initialization binds the single local runtime file."""
|
|
111
111
|
_bind_file(workspace.tables_path, workspace_uid=workspace.uid, purpose="runtime")
|
|
112
112
|
|
|
113
113
|
|
|
@@ -161,7 +161,6 @@ def select_local_workspace(
|
|
|
161
161
|
[
|
|
162
162
|
str(source.repository_root.resolve()),
|
|
163
163
|
source.canonical_repository_identity,
|
|
164
|
-
source.repository_branch,
|
|
165
164
|
],
|
|
166
165
|
separators=(",", ":"),
|
|
167
166
|
)
|