matrx-orm 3.1.155__tar.gz → 3.1.157__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.
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/PKG-INFO +2 -2
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/__init__.py +16 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/core/async_db_manager.py +9 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/exceptions.py +87 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/platform_access.py +73 -1
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/pyproject.toml +2 -2
- matrx_orm-3.1.157/tests/level1/test_orm_banners_are_client_safe.py +73 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/.gitignore +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/AGENTS.md +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/BASE_CLASS_METHODS.md +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/CLAUDE.md +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/MODEL_API.md +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/README.md +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/database/orm/extended/managers/ai_model_base.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/docs/migrations.md +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/FEATURE.md +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/MODULE_README.md +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/adapters/MODULE_README.md +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/adapters/__init__.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/adapters/async_postgresql.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/adapters/base_adapter.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/adapters/postgresql.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/adapters/postgrest_client_adapter.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/adapters/supabase_adapter.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/admin/FEATURE.md +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/admin/__init__.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/admin/router.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/api/__init__.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/api/auth.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/api/config.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/api/handlers.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/api/protocol.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/api/server.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/associations.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/cache_debug.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/catalog.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/catalog_sql.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/client/MODULE_README.md +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/client/__init__.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/client/postgres_connection.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/client/postgrest.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/client/supabase_auth.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/client/supabase_config.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/client/supabase_manager.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/core/EXTENDED-TASK.md +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/core/FEATURE.md +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/core/MODULE_README.md +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/core/RELATIONS-TASKS.md +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/core/TASKS.md +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/core/__init__.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/core/base.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/core/config.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/core/connections.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/core/db_function.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/core/diagnostics.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/core/expressions.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/core/extended.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/core/fields.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/core/introspection.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/core/listen.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/core/loop_filters.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/core/model_dto.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/core/model_view.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/core/one_database.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/core/paginator.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/core/pool_maintenance.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/core/pool_watch.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/core/pooler_role.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/core/pydantic_bridge.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/core/registry.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/core/relations.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/core/resilience.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/core/rls_session.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/core/session_context.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/core/signals.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/core/tls.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/core/transaction.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/core/types.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/core/write_queue.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/core/write_retry.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/entity.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/error_handling.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/extended/__init__.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/extended/app_error_handler.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/identity_rule.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/local_sqlite.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/middleware/__init__.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/middleware/base.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/migrations/MODULE_README.md +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/migrations/__init__.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/migrations/cli.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/migrations/ddl.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/migrations/diff.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/migrations/executor.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/migrations/integration.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/migrations/loader.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/migrations/operations.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/migrations/state.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/migrations/table_filter.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/no_org_assignment.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/operations/FEATURE.md +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/operations/MODULE_README.md +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/operations/__init__.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/operations/bulk_update_values.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/operations/catalog_select.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/operations/conflict.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/operations/conflict_writes.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/operations/create.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/operations/db_functions.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/operations/delete.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/operations/dynamic_admin.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/operations/dynamic_crud.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/operations/graph_walk.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/operations/latest_rows.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/operations/queue_claim.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/operations/read.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/operations/relational_backfill.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/operations/staging_load.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/operations/update.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/platform_db.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/py.typed +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/pytest_lock_guard.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/pytest_plugin.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/python_sql/MODULE_README.md +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/python_sql/__init__.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/python_sql/db_objects.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/python_sql/table_detailed_relationships.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/python_sql/table_typescript_relationship.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/query/FEATURE.md +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/query/MODULE_README.md +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/query/__init__.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/query/builder.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/query/executor.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/resources/__init__.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/resources/additional-assigners-2026-09-12.json +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/resources/org_assignment_trigger_baseline.json +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/schema_builder/FEATURE.md +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/schema_builder/MODULE_README.md +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/schema_builder/__init__.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/schema_builder/code_handler.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/schema_builder/codegen_writer.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/schema_builder/columns.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/schema_builder/common.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/schema_builder/diff_preview.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/schema_builder/entity_capabilities.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/schema_builder/generator.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/schema_builder/helpers/__init__.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/schema_builder/helpers/base_generators.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/schema_builder/helpers/entity_generators.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/schema_builder/helpers/git_checker.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/schema_builder/package_wiring.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/schema_builder/relationships.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/schema_builder/runner.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/schema_builder/schema.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/schema_builder/schema_manager.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/schema_builder/tables.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/schema_builder/views.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/secrets_battery/FEATURE.md +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/secrets_battery/__init__.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/secrets_battery/attachments.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/secrets_battery/crypto.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/secrets_battery/host_authorization.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/secrets_battery/items.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/secrets_battery/model.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/secrets_battery/mutation_receipts.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/secrets_battery/org_service.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/secrets_battery/service.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/session/README.md +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/session/__init__.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/session/coalesce.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/session/dag.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/session/errors.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/session/fallback.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/session/flush.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/session/lifecycle.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/session/managed.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/session/op.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/session/reads.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/session/session.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/session/telemetry.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/sql_executor/MODULE_README.md +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/sql_executor/__init__.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/sql_executor/executor.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/sql_executor/queries.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/sql_executor/registry.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/sql_executor/types.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/sql_executor/utils.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/state.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/utils/__init__.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/utils/sql_utils.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/matrx_orm/utils/type_converters.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/scripts/git-branches.sh +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/scripts/publish.sh +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/scripts/release.sh +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/MODULE_README.md +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/__init__.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/conftest.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/MODULE_README.md +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/__init__.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_adapter_registry.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_admin_db_columns.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_admin_response_rendering.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_admin_search_negation.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_admin_search_sentinels.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_advisory_lock.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_agent_message.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_api_auth.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_api_config.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_api_handlers.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_api_protocol.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_array_agg_order_by.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_associations.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_associations_wiring.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_bulk_hydration_offload.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_bulk_update_by_pk.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_bulk_upsert_increment_set_fields.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_cache_debug.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_call_function.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_case_when.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_catalog.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_committed_row_guard.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_composite_pk_filter.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_composite_pk_write_paths.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_config.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_conflict_target.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_conflict_writes.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_connection_codecs.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_connection_poison_guard.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_connection_primitives.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_count_composite_distinct.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_count_limit_param_leak.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_db_function_field.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_ddl_generator.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_deadlock_retry.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_derived_table.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_dirty_tracking.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_dynamic_crud.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_exceptions.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_execute_query_integrity_mapping.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_expression_primitives.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_fields.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_filter_jsonb_agg_array_index.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_from_alias.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_fts.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_func_expression_args.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_graph_walk.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_having_annotate_alias.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_insert_ignore_and_admin_primitives.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_introspect_rls_policies.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_join_and_aggregate.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_latest_rows.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_listen_notify.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_local_sqlite.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_lock_contention_retry.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_managed_write_guard.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_matrx_entity.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_migration_diff_types.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_migration_loader.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_model_instance.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_model_meta.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_optimistic_concurrency.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_order_by_expression.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_org_assignment_inventory.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_parameter_name_hydration.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_patch_jsonb_path.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_persisted_count.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_pool_holder_census.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_pool_loop_recreation.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_pool_maintenance.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_postgrest_filters.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_pydantic_bridge.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_query_builder.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_query_error_detail.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_query_executor_sql.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_query_timeout.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_querybuilder_clone_semantics.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_queue_claim.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_read_connection_retry.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_registry.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_registry_multi_database.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_registry_multi_schema.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_relational_backfill.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_relations.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_resilience.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_rls_session_scope.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_schema_exists.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_session_advisory_lock.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_standalone_write_session_context.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_state_cache.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_subquery_filter_raw.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_subquery_in_filter.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_subquery_nested_expressions.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_supabase_auth.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_supabase_config.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_tls.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_transaction_database_identity.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_typed_join_projection.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_typed_predicates.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_update_case_expression.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_update_subquery.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_update_with_rebase.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_upsert_default_leak.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_upsert_with_conflict.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_values_jsonb_decode.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_watched_lifecycle.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_write_queue_deadline.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level1/test_write_retry_semantics.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level2/MODULE_README.md +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level2/__init__.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level2/conftest.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level2/test_bulk_ops.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level2/test_cache_integration.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level2/test_crud.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level2/test_foreign_keys.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level2/test_m2m.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level2/test_manager.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level2/test_migrations_live.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level2/test_query_execution.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level2/test_schema_diff.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/level2/verify_committed_row_guard_pg17.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/live_pooler_role.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/sample_project/.env.example +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/sample_project/README.md +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/sample_project/__init__.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/sample_project/generate.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/sample_project/generated/.gitkeep +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/sample_project/matrx_orm.yaml +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/sample_project/test_schema_generation.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/sample_project_desktop/.env.example +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/sample_project_desktop/README.md +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/sample_project_desktop/__init__.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/sample_project_desktop/client_example.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/sample_project_desktop/client_example.ts +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/sample_project_desktop/client_supabase_example.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/sample_project_desktop/server.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/schema/entity_tests.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/schema/test_base_generation.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/schema/test_composite_pk_fk_generation.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/schema/test_composite_unique_generation.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/schema/test_dto_identity_generation.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/schema/test_entity_capability_generation.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/schema/test_enum_ordering.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/schema/test_generate_schema.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/schema/test_junction_analysis.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/schema/test_multi_schema_output.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/schema/test_schema_analysis.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/schema/test_sql_expression_defaults.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/schema/test_table_relationships_query.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/schema/test_view_generation.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/schema_builder/test_array_default_parsing.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/schema_builder/test_focused_generation_plan.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/schema_builder/test_host_models_aggregator.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/session/__init__.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/session/conftest.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/session/test_cache_no_downgrade.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/session/test_capture_poison_proof.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/session/test_coalesce.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/session/test_dag.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/session/test_disk_spill_fallback.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/session/test_flush_individual_fallback.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/session/test_governed_write.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/session/test_managed.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/session/test_op_enqueue_site.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/session/test_reads.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/session/test_record_error_bounded_insert.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/session/test_record_error_storm.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/session/test_session.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/session/test_spill_guard_plugin.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/test_array_arg_element_type.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/test_database_name_alias.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/test_db_functions.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/test_dynamic_select_unregistered.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/test_immutable_insert_or_exact_verify.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/test_keyed_digest.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/test_model_cls_refactor.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/test_no_blocking_asyncpg_tls.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/test_one_database.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/test_order_by_desc_nulls_last.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/test_pooler_role_guard.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/test_secrets_battery.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/test_secrets_minting_keys.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/test_shared_lock_guard.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/test_sql_param_casts.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/test_sync_twins_guard.py +0 -0
- {matrx_orm-3.1.155 → matrx_orm-3.1.157}/tests/test_user_visible_lookup.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: matrx-orm
|
|
3
|
-
Version: 3.1.
|
|
3
|
+
Version: 3.1.157
|
|
4
4
|
Summary: Async-first PostgreSQL ORM with bidirectional migrations, schema introspection, many-to-many relationships, and built-in state caching
|
|
5
5
|
Project-URL: Homepage, https://github.com/AI-Matrix-Engine/aidream-current
|
|
6
6
|
Project-URL: Repository, https://github.com/AI-Matrix-Engine/aidream-current
|
|
@@ -25,7 +25,7 @@ Requires-Python: >=3.13
|
|
|
25
25
|
Requires-Dist: asyncpg>=0.31.0
|
|
26
26
|
Requires-Dist: cryptography>=43.0
|
|
27
27
|
Requires-Dist: gitpython>=3.1.40
|
|
28
|
-
Requires-Dist: matrx-utils>=2.0.
|
|
28
|
+
Requires-Dist: matrx-utils>=2.0.45
|
|
29
29
|
Requires-Dist: psycopg-pool>=3.2.5
|
|
30
30
|
Requires-Dist: psycopg[binary]>=3.2.5
|
|
31
31
|
Requires-Dist: python-dotenv>=1.0
|
|
@@ -40,10 +40,17 @@ from .entity import EntityCapabilityError, MatrxEntity
|
|
|
40
40
|
from .platform_access import (
|
|
41
41
|
ACCESS_POLICY_FUNCTION,
|
|
42
42
|
ACCESS_POLICY_SCHEMA,
|
|
43
|
+
DB_PERMISSION_LEVELS,
|
|
44
|
+
PERMISSION_LEVEL_LABELS,
|
|
45
|
+
PERMISSION_LEVEL_RANK,
|
|
46
|
+
PERMISSION_LEVELS,
|
|
43
47
|
EdgeAccessRequirement,
|
|
48
|
+
PermissionLevel,
|
|
44
49
|
configure_platform_access,
|
|
50
|
+
permission_level_rank,
|
|
45
51
|
platform_access_check,
|
|
46
52
|
platform_edge_requirement,
|
|
53
|
+
to_db_permission_level,
|
|
47
54
|
verify_platform_access_wiring,
|
|
48
55
|
)
|
|
49
56
|
from .platform_db import (
|
|
@@ -301,6 +308,7 @@ from .exceptions import (
|
|
|
301
308
|
ORMException,
|
|
302
309
|
ParameterError,
|
|
303
310
|
PermissionDeniedError,
|
|
311
|
+
RecordNotAvailableError,
|
|
304
312
|
PoolAcquireTimeoutError,
|
|
305
313
|
LockContentionError,
|
|
306
314
|
ReadOnlyTransactionError,
|
|
@@ -408,6 +416,13 @@ __all__ = [
|
|
|
408
416
|
"EdgeAccessRequirement",
|
|
409
417
|
"ACCESS_POLICY_SCHEMA",
|
|
410
418
|
"ACCESS_POLICY_FUNCTION",
|
|
419
|
+
"PERMISSION_LEVELS",
|
|
420
|
+
"PERMISSION_LEVEL_RANK",
|
|
421
|
+
"PERMISSION_LEVEL_LABELS",
|
|
422
|
+
"DB_PERMISSION_LEVELS",
|
|
423
|
+
"PermissionLevel",
|
|
424
|
+
"permission_level_rank",
|
|
425
|
+
"to_db_permission_level",
|
|
411
426
|
"host_db_config_name",
|
|
412
427
|
"HOST_DB_CONFIG_NAME_ENV",
|
|
413
428
|
"platform_connection_url",
|
|
@@ -746,6 +761,7 @@ __all__ = [
|
|
|
746
761
|
"MigrationError",
|
|
747
762
|
"ParameterError",
|
|
748
763
|
"PermissionDeniedError",
|
|
764
|
+
"RecordNotAvailableError",
|
|
749
765
|
"SchemaMismatchError",
|
|
750
766
|
"format_db_failure_banner",
|
|
751
767
|
"parse_undefined_identifier",
|
|
@@ -39,6 +39,7 @@ from matrx_orm.exceptions import (
|
|
|
39
39
|
QueryError,
|
|
40
40
|
QueryTimeoutError,
|
|
41
41
|
ReadOnlyTransactionError,
|
|
42
|
+
RecordNotAvailableError,
|
|
42
43
|
SchemaMismatchError,
|
|
43
44
|
StateError,
|
|
44
45
|
UnknownDatabaseError,
|
|
@@ -1286,6 +1287,10 @@ class AsyncDatabaseManager:
|
|
|
1286
1287
|
raise PermissionDeniedError(
|
|
1287
1288
|
original_error=e, query=query, args=args, config_name=config_name
|
|
1288
1289
|
) from None
|
|
1290
|
+
except asyncpg.exceptions.NoDataFoundError as e:
|
|
1291
|
+
raise RecordNotAvailableError(
|
|
1292
|
+
original_error=e, query=query, args=args, config_name=config_name
|
|
1293
|
+
) from None
|
|
1289
1294
|
except asyncpg.exceptions.ReadOnlySQLTransactionError as e:
|
|
1290
1295
|
raise ReadOnlyTransactionError(original_error=e) from None
|
|
1291
1296
|
except TimeoutError as e:
|
|
@@ -1487,6 +1492,10 @@ class AsyncDatabaseManager:
|
|
|
1487
1492
|
raise PermissionDeniedError(
|
|
1488
1493
|
original_error=e, query=query, args=args, config_name=config_name
|
|
1489
1494
|
) from None
|
|
1495
|
+
except asyncpg.exceptions.NoDataFoundError as e:
|
|
1496
|
+
raise RecordNotAvailableError(
|
|
1497
|
+
original_error=e, query=query, args=args, config_name=config_name
|
|
1498
|
+
) from None
|
|
1490
1499
|
except TimeoutError as e:
|
|
1491
1500
|
# asyncpg's command_timeout fired — query held a
|
|
1492
1501
|
# connection but didn't return in time. See the twin
|
|
@@ -1946,6 +1946,93 @@ class PermissionDeniedError(DatabaseError):
|
|
|
1946
1946
|
return f"{_RED}{body}{_RESET}"
|
|
1947
1947
|
|
|
1948
1948
|
|
|
1949
|
+
class RecordNotAvailableError(DatabaseError):
|
|
1950
|
+
"""The database refused the statement with SQLSTATE ``P0002`` (no_data_found).
|
|
1951
|
+
|
|
1952
|
+
Our SECURITY INVOKER functions and triggers raise ``P0002`` as the platform's
|
|
1953
|
+
HONEST ACCESS REFUSAL: "dataset <id> is not available to this account — it
|
|
1954
|
+
may not exist, or your access may not reach it" (the D167 class; see
|
|
1955
|
+
matrx-frontend ``migrations/invoker_fns_honest_access_error.sql``). That
|
|
1956
|
+
sentence is written for a person. Before 2026-09-17 it fell through to
|
|
1957
|
+
``UnknownDatabaseError`` and a Studio user saw the whole terminal banner —
|
|
1958
|
+
SQL, bound args and ORM-maintainer hints — instead of it.
|
|
1959
|
+
|
|
1960
|
+
``person_message`` is the sentence a client may show (plus a remedy);
|
|
1961
|
+
``str(exc)`` stays the developer banner for logs. Not retryable: access does
|
|
1962
|
+
not change between attempts.
|
|
1963
|
+
"""
|
|
1964
|
+
|
|
1965
|
+
#: The honest-refusal wording our functions use. Anything else raised under
|
|
1966
|
+
#: P0002 (``SELECT … INTO STRICT`` finding no row) is ours to word.
|
|
1967
|
+
_HONEST_REFUSAL = "is not available to this account"
|
|
1968
|
+
|
|
1969
|
+
def __init__(
|
|
1970
|
+
self,
|
|
1971
|
+
*,
|
|
1972
|
+
original_error: BaseException | None = None,
|
|
1973
|
+
query: str | None = None,
|
|
1974
|
+
args: Any = None,
|
|
1975
|
+
config_name: str | None = None,
|
|
1976
|
+
) -> None:
|
|
1977
|
+
info = describe_db_exception(original_error)
|
|
1978
|
+
details: dict[str, Any] = {
|
|
1979
|
+
"query": query,
|
|
1980
|
+
"args": args if args is not None else [],
|
|
1981
|
+
"config_name": config_name,
|
|
1982
|
+
"sqlstate": info.sqlstate,
|
|
1983
|
+
"db_error": info.as_text(),
|
|
1984
|
+
"db_hint": info.hint,
|
|
1985
|
+
}
|
|
1986
|
+
self.db_message = info.message
|
|
1987
|
+
super().__init__(
|
|
1988
|
+
message=f"Record not available to this account: {info.message}",
|
|
1989
|
+
model=None,
|
|
1990
|
+
details=details,
|
|
1991
|
+
)
|
|
1992
|
+
|
|
1993
|
+
@property
|
|
1994
|
+
def person_message(self) -> str:
|
|
1995
|
+
"""One plain sentence with a remedy. Never SQL, args, or ids of other rows."""
|
|
1996
|
+
reason = (self.db_message or "").strip().rstrip(".")
|
|
1997
|
+
if self._HONEST_REFUSAL in reason:
|
|
1998
|
+
first = reason[0].upper() + reason[1:]
|
|
1999
|
+
return (
|
|
2000
|
+
f"{first}. Choose one this account can open, or ask its owner to share it."
|
|
2001
|
+
)
|
|
2002
|
+
return (
|
|
2003
|
+
"Something this step needs is not available to this account — it may not "
|
|
2004
|
+
"exist, or your access may not reach it. Check the step's selection, or ask "
|
|
2005
|
+
"its owner to share it."
|
|
2006
|
+
)
|
|
2007
|
+
|
|
2008
|
+
def format_message(self) -> str:
|
|
2009
|
+
sqlstate = self._str("sqlstate")
|
|
2010
|
+
db_error = self._str("db_error")
|
|
2011
|
+
query = self._str("query")
|
|
2012
|
+
args = self.details.get("args", [])
|
|
2013
|
+
lines = ["\n" + "-" * 80]
|
|
2014
|
+
lines.append("Matrx ORM | RecordNotAvailableError")
|
|
2015
|
+
lines.append("")
|
|
2016
|
+
lines.append(self.message)
|
|
2017
|
+
if sqlstate:
|
|
2018
|
+
lines.append(f" SQLSTATE: {sqlstate}")
|
|
2019
|
+
if db_error:
|
|
2020
|
+
lines.append(f" DB error: {db_error}")
|
|
2021
|
+
if query:
|
|
2022
|
+
short_query = str(query)[:300] + ("..." if len(str(query)) > 300 else "")
|
|
2023
|
+
lines.append(f" Query: {short_query}")
|
|
2024
|
+
if args:
|
|
2025
|
+
lines.append(f" Args: {args}")
|
|
2026
|
+
lines.append("")
|
|
2027
|
+
lines.append("Hint:")
|
|
2028
|
+
lines.append(" - A database function refused this with P0002 — usually the honest access")
|
|
2029
|
+
lines.append(" refusal: RLS hides the row from this caller, or it does not exist.")
|
|
2030
|
+
lines.append(" - Not retryable. The person-facing sentence is ``person_message``.")
|
|
2031
|
+
lines.append("-" * 80 + "\n")
|
|
2032
|
+
body = "\n".join(lines)
|
|
2033
|
+
return f"{_RED}{body}{_RESET}"
|
|
2034
|
+
|
|
2035
|
+
|
|
1949
2036
|
class UnknownDatabaseError(ORMException):
|
|
1950
2037
|
"""Raised when an unexpected database error occurs, capturing full context.
|
|
1951
2038
|
|
|
@@ -39,7 +39,79 @@ from __future__ import annotations
|
|
|
39
39
|
from dataclasses import dataclass
|
|
40
40
|
from typing import Literal
|
|
41
41
|
|
|
42
|
-
|
|
42
|
+
# ── THE LADDER ────────────────────────────────────────────────────────────────
|
|
43
|
+
#
|
|
44
|
+
# The access levels are ``viewer`` · ``commenter`` · ``editor`` · ``admin``
|
|
45
|
+
# (AI Matrx Data Doctrine R18, 2026-09-10; see
|
|
46
|
+
# common-docs/systems/platform/access/DECISIONS.md). This is THE ONE PLACE they
|
|
47
|
+
# are declared on the Python side — every rank map, label map and level tuple in
|
|
48
|
+
# aidream derives from it, so a level cannot be present in one ladder and absent
|
|
49
|
+
# from another.
|
|
50
|
+
#
|
|
51
|
+
# It matters because the failure is SILENT. A rank map that omits a level hands
|
|
52
|
+
# a ``dict.get(level, 0)`` caller a 0, the comparison is ``False``, and the
|
|
53
|
+
# holder is refused with nothing written anywhere. A ``not in {...}`` validation
|
|
54
|
+
# set that omits one rejects a legitimate grant as "unsupported".
|
|
55
|
+
#
|
|
56
|
+
# ``PERMISSION_LEVELS`` (the CODE ladder) deliberately runs WIDER than
|
|
57
|
+
# ``DB_PERMISSION_LEVELS`` (what ``public.permission_level`` holds today):
|
|
58
|
+
# ``commenter`` is not in the database enum yet. Reading, ranking and labelling
|
|
59
|
+
# always use the code ladder, so nothing needs an edit the day the enum gains
|
|
60
|
+
# it; nothing breaks meanwhile, because the value simply never arrives. WRITING
|
|
61
|
+
# a level to the database narrows through ``to_db_permission_level`` first.
|
|
62
|
+
PERMISSION_LEVELS: tuple[str, ...] = ("viewer", "commenter", "editor", "admin")
|
|
63
|
+
|
|
64
|
+
PermissionLevel = Literal["viewer", "commenter", "editor", "admin"]
|
|
65
|
+
|
|
66
|
+
#: Ordinal rank, 1-based, derived from the ladder so it can never drift out of step.
|
|
67
|
+
PERMISSION_LEVEL_RANK: dict[str, int] = {level: index + 1 for index, level in enumerate(PERMISSION_LEVELS)}
|
|
68
|
+
|
|
69
|
+
#: Human labels — a level that reaches a screen or a log is never rendered blank.
|
|
70
|
+
PERMISSION_LEVEL_LABELS: dict[str, str] = {
|
|
71
|
+
"viewer": "Viewer",
|
|
72
|
+
"commenter": "Commenter",
|
|
73
|
+
"editor": "Editor",
|
|
74
|
+
"admin": "Full access",
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
#: What ``public.permission_level`` accepts RIGHT NOW. Widen this the same
|
|
78
|
+
#: migration that runs
|
|
79
|
+
#: ``ALTER TYPE public.permission_level ADD VALUE 'commenter' BEFORE 'editor'``.
|
|
80
|
+
DB_PERMISSION_LEVELS: tuple[str, ...] = ("viewer", "editor", "admin")
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def permission_level_rank(level: str) -> int:
|
|
84
|
+
"""Rank a level, refusing to answer silently for one off the ladder.
|
|
85
|
+
|
|
86
|
+
The old shape — ``LEVEL_ORDER.get(level, 0)`` — quietly ranked an unknown
|
|
87
|
+
level at the bottom and denied it with no trace. This raises by name with
|
|
88
|
+
the remedy instead.
|
|
89
|
+
"""
|
|
90
|
+
try:
|
|
91
|
+
return PERMISSION_LEVEL_RANK[level]
|
|
92
|
+
except KeyError:
|
|
93
|
+
raise ValueError(
|
|
94
|
+
f"Unknown permission level {level!r}. Known levels are "
|
|
95
|
+
f"{', '.join(PERMISSION_LEVELS)} — add it to PERMISSION_LEVELS in "
|
|
96
|
+
"matrx_orm.platform_access if the database gained a new value."
|
|
97
|
+
) from None
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def to_db_permission_level(level: str) -> str:
|
|
101
|
+
"""Narrow a code-ladder level to one the database can actually store.
|
|
102
|
+
|
|
103
|
+
Refuses by name with the remedy rather than letting Postgres answer with an
|
|
104
|
+
opaque ``invalid input value for enum public.permission_level``.
|
|
105
|
+
"""
|
|
106
|
+
permission_level_rank(level) # rejects an off-ladder level first
|
|
107
|
+
if level not in DB_PERMISSION_LEVELS:
|
|
108
|
+
raise ValueError(
|
|
109
|
+
f"Permission level {level!r} is not in the database enum "
|
|
110
|
+
f"public.permission_level (it holds {', '.join(DB_PERMISSION_LEVELS)}). "
|
|
111
|
+
f"Apply ALTER TYPE public.permission_level ADD VALUE '{level}' before "
|
|
112
|
+
"granting this level."
|
|
113
|
+
)
|
|
114
|
+
return level
|
|
43
115
|
|
|
44
116
|
#: The canonical policy function: ``iam.has_access_for(uuid, text, uuid, permission_level)``.
|
|
45
117
|
ACCESS_POLICY_SCHEMA = "iam"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "matrx-orm"
|
|
3
|
-
version = "3.1.
|
|
3
|
+
version = "3.1.157"
|
|
4
4
|
description = "Async-first PostgreSQL ORM with bidirectional migrations, schema introspection, many-to-many relationships, and built-in state caching"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
license = { text = "MIT" }
|
|
@@ -41,7 +41,7 @@ dependencies = [
|
|
|
41
41
|
"gitpython>=3.1.40",
|
|
42
42
|
"psycopg[binary]>=3.2.5",
|
|
43
43
|
"psycopg-pool>=3.2.5",
|
|
44
|
-
"matrx-utils>=2.0.
|
|
44
|
+
"matrx-utils>=2.0.45",
|
|
45
45
|
"pyyaml>=6.0.3",
|
|
46
46
|
"python-dotenv>=1.0",
|
|
47
47
|
"cryptography>=43.0",
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"""Every ORM error a client might be shown reduces to its reason — never SQL,
|
|
2
|
+
bound args, ANSI, a traceback or maintainer hints — and the P0002 honest access
|
|
3
|
+
refusal is its own class with a person-facing sentence.
|
|
4
|
+
|
|
5
|
+
Live 2026-09-17: a Studio user saw ``UnknownDatabaseError``'s full banner (the
|
|
6
|
+
INSERT and its Args: their user id and row data) because asyncpg's
|
|
7
|
+
``NoDataFoundError`` had no catch and the engine rendered ``str(exc)``.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
import asyncpg
|
|
13
|
+
import pytest
|
|
14
|
+
from matrx_utils import client_error_text
|
|
15
|
+
|
|
16
|
+
from matrx_orm.exceptions import (
|
|
17
|
+
PermissionDeniedError,
|
|
18
|
+
QueryTimeoutError,
|
|
19
|
+
RecordNotAvailableError,
|
|
20
|
+
UnknownDatabaseError,
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
_SECRET = "4cf62e4e-2679-484c-a1ab-0e62d4e1c3aa"
|
|
24
|
+
_QUERY = "INSERT INTO workbench.udt_dataset_rows (data, user_id) VALUES ($1, $2)"
|
|
25
|
+
_ARGS = ['{"note": "private row"}', _SECRET]
|
|
26
|
+
_REFUSAL = "dataset d-1 is not available to this account — it may not exist, or your access may not reach it"
|
|
27
|
+
_LEAKS = ("\x1b", "[91m", "Args:", "Query:", "INSERT", _SECRET, "private row", "Traceback", "Hint:", "Matrx ORM", "-" * 20)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def _banners() -> list[BaseException]:
|
|
31
|
+
return [
|
|
32
|
+
UnknownDatabaseError(
|
|
33
|
+
operation="execute_query",
|
|
34
|
+
query=_QUERY,
|
|
35
|
+
args=_ARGS,
|
|
36
|
+
traceback='Traceback (most recent call last):\n File "x.py", line 1\n',
|
|
37
|
+
original_error=asyncpg.exceptions.NoDataFoundError(_REFUSAL),
|
|
38
|
+
),
|
|
39
|
+
PermissionDeniedError(
|
|
40
|
+
original_error=asyncpg.exceptions.InsufficientPrivilegeError("permission denied for table t"),
|
|
41
|
+
query=_QUERY,
|
|
42
|
+
args=_ARGS,
|
|
43
|
+
),
|
|
44
|
+
RecordNotAvailableError(
|
|
45
|
+
original_error=asyncpg.exceptions.NoDataFoundError(_REFUSAL), query=_QUERY, args=_ARGS
|
|
46
|
+
),
|
|
47
|
+
QueryTimeoutError(operation="execute_query", query=_QUERY, args=_ARGS, original_error=TimeoutError()),
|
|
48
|
+
]
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
@pytest.mark.parametrize("exc", _banners(), ids=lambda e: type(e).__name__)
|
|
52
|
+
def test_real_orm_banner_reduces_to_its_reason(exc: BaseException) -> None:
|
|
53
|
+
raw = str(exc)
|
|
54
|
+
assert "Args:" in raw # the render really carries the bound args
|
|
55
|
+
out = client_error_text(raw)
|
|
56
|
+
assert out.strip()
|
|
57
|
+
for leak in _LEAKS:
|
|
58
|
+
assert leak not in out, f"{type(exc).__name__} leaks {leak!r}:\n{out}"
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def test_honest_refusal_has_a_person_sentence_with_a_remedy() -> None:
|
|
62
|
+
exc = RecordNotAvailableError(original_error=asyncpg.exceptions.NoDataFoundError(_REFUSAL), query=_QUERY, args=_ARGS)
|
|
63
|
+
msg = exc.person_message
|
|
64
|
+
assert msg.startswith("Dataset d-1 is not available to this account")
|
|
65
|
+
assert "ask its owner to share it" in msg
|
|
66
|
+
for leak in _LEAKS:
|
|
67
|
+
assert leak not in msg
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def test_other_p0002_gets_a_generic_honest_sentence() -> None:
|
|
71
|
+
exc = RecordNotAvailableError(original_error=asyncpg.exceptions.NoDataFoundError("query returned no rows"))
|
|
72
|
+
assert "not available to this account" in exc.person_message
|
|
73
|
+
assert "query returned no rows" not in exc.person_message
|
|
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
|
|
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
|
|
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
|
|
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
|