matrx-orm 3.0.30__tar.gz → 3.0.32__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.0.30 → matrx_orm-3.0.32}/PKG-INFO +3 -1
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/README.md +2 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/pyproject.toml +1 -1
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/schema_builder/columns.py +4 -2
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/schema_builder/diff_preview.py +42 -1
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/schema_builder/schema.py +110 -7
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/schema_builder/tables.py +8 -2
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/tests/sample_project/matrx_orm.yaml +19 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/.arman/pending/versioning/INITIAL.md +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/.env.example +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/.github/workflows/publish.yml +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/.gitignore +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/.python-version +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/.vscode/settings.json +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/CLAUDE.md +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/DESKTOP-API-INTEGRATION.md +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/MIGRATIONS.md +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/MODULE_README.md +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/RESERVED_NAMES.md +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/TASKS-TEMPLATE.md +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/TASKS.md +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/TRANSACTION_POOLER_PLAN.MD +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/WRITE-QUEUE-UPGRADE.md +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/database/orm/extended/managers/ai_model_base.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/docs/migrations.md +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/extended_jan5_backup.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/main.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/release.sh +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/scripts/git-branches.sh +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/scripts/publish.sh +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/scripts/release.sh +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/MODULE_README.md +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/MODULE_README.md +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/__init__.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/adapters/MODULE_README.md +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/adapters/__init__.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/adapters/async_postgresql.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/adapters/base_adapter.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/adapters/postgresql.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/adapters/postgrest_client_adapter.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/adapters/supabase_adapter.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/api/__init__.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/api/auth.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/api/config.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/api/handlers.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/api/protocol.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/api/server.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/client/MODULE_README.md +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/client/__init__.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/client/postgres_connection.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/client/postgrest.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/client/supabase_auth.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/client/supabase_config.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/client/supabase_manager.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/core/EXTENDED-TASK.md +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/core/MODULE_README.md +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/core/RELATIONS-TASKS.md +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/core/TASKS.md +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/core/__init__.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/core/async_db_manager.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/core/base.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/core/config.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/core/expressions.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/core/extended.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/core/fields.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/core/model_dto.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/core/model_view.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/core/paginator.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/core/pydantic_bridge.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/core/registry.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/core/relations.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/core/signals.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/core/transaction.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/core/types.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/core/write_queue.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/error_handling.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/exceptions.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/extended/__init__.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/extended/app_error_handler.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/middleware/__init__.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/middleware/base.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/migrations/MODULE_README.md +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/migrations/__init__.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/migrations/cli.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/migrations/ddl.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/migrations/diff.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/migrations/executor.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/migrations/integration.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/migrations/loader.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/migrations/operations.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/migrations/state.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/migrations/table_filter.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/operations/MODULE_README.md +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/operations/__init__.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/operations/create.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/operations/delete.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/operations/read.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/operations/update.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/py.typed +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/python_sql/MODULE_README.md +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/python_sql/__init__.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/python_sql/db_objects.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/python_sql/table_detailed_relationships.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/python_sql/table_typescript_relationship.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/query/MODULE_README.md +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/query/__init__.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/query/builder.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/query/executor.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/schema_builder/MODULE_README.md +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/schema_builder/__init__.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/schema_builder/code_handler.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/schema_builder/common.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/schema_builder/generator.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/schema_builder/helpers/__init__.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/schema_builder/helpers/base_generators.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/schema_builder/helpers/entity_generators.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/schema_builder/helpers/git_checker.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/schema_builder/relationships.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/schema_builder/runner.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/schema_builder/schema_manager.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/schema_builder/views.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/sql_executor/MODULE_README.md +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/sql_executor/__init__.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/sql_executor/executor.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/sql_executor/queries.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/sql_executor/registry.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/sql_executor/types.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/sql_executor/utils.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/state.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/utils/__init__.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/utils/sql_utils.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/utils/type_converters.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/tests/MODULE_README.md +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/tests/__init__.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/tests/conftest.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/tests/level1/MODULE_README.md +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/tests/level1/__init__.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/tests/level1/test_api_auth.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/tests/level1/test_api_config.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/tests/level1/test_api_handlers.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/tests/level1/test_api_protocol.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/tests/level1/test_config.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/tests/level1/test_ddl_generator.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/tests/level1/test_exceptions.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/tests/level1/test_fields.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/tests/level1/test_migration_diff_types.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/tests/level1/test_migration_loader.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/tests/level1/test_model_instance.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/tests/level1/test_model_meta.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/tests/level1/test_postgrest_filters.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/tests/level1/test_query_builder.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/tests/level1/test_query_executor_sql.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/tests/level1/test_registry.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/tests/level1/test_relations.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/tests/level1/test_state_cache.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/tests/level1/test_supabase_auth.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/tests/level1/test_supabase_config.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/tests/level2/MODULE_README.md +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/tests/level2/__init__.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/tests/level2/conftest.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/tests/level2/test_bulk_ops.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/tests/level2/test_cache_integration.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/tests/level2/test_crud.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/tests/level2/test_foreign_keys.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/tests/level2/test_m2m.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/tests/level2/test_manager.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/tests/level2/test_migrations_live.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/tests/level2/test_query_execution.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/tests/level2/test_schema_diff.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/tests/sample_project/.env.example +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/tests/sample_project/README.md +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/tests/sample_project/__init__.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/tests/sample_project/generate.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/tests/sample_project/generated/.gitkeep +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/tests/sample_project/test_schema_generation.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/tests/sample_project_desktop/.env.example +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/tests/sample_project_desktop/README.md +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/tests/sample_project_desktop/__init__.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/tests/sample_project_desktop/client_example.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/tests/sample_project_desktop/client_example.ts +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/tests/sample_project_desktop/client_supabase_example.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/tests/sample_project_desktop/server.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/tests/schema/entity_tests.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/tests/schema/test_base_generation.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/tests/schema/test_generate_schema.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/tests/test_model_cls_refactor.py +0 -0
- {matrx_orm-3.0.30 → matrx_orm-3.0.32}/uv.lock +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: matrx-orm
|
|
3
|
-
Version: 3.0.
|
|
3
|
+
Version: 3.0.32
|
|
4
4
|
Summary: Async-first PostgreSQL ORM with bidirectional migrations, schema introspection, many-to-many relationships, and built-in state caching. Works with any PostgreSQL database.
|
|
5
5
|
Project-URL: Homepage, https://github.com/armanisadeghi/matrx-orm
|
|
6
6
|
Project-URL: Repository, https://github.com/armanisadeghi/matrx-orm
|
|
@@ -1838,6 +1838,8 @@ When you run the schema builder against a database that has `vector(n)` columns,
|
|
|
1838
1838
|
|
|
1839
1839
|
| Version | Highlights |
|
|
1840
1840
|
|---|---|
|
|
1841
|
+
| **v3.0.32** | Patch release |
|
|
1842
|
+
| **v3.0.31** | Patch release |
|
|
1841
1843
|
| **v3.0.30** | Patch release |
|
|
1842
1844
|
| **v3.0.29** | Patch release |
|
|
1843
1845
|
| **v3.0.28** | Patch release |
|
|
@@ -1795,6 +1795,8 @@ When you run the schema builder against a database that has `vector(n)` columns,
|
|
|
1795
1795
|
|
|
1796
1796
|
| Version | Highlights |
|
|
1797
1797
|
|---|---|
|
|
1798
|
+
| **v3.0.32** | Patch release |
|
|
1799
|
+
| **v3.0.31** | Patch release |
|
|
1798
1800
|
| **v3.0.30** | Patch release |
|
|
1799
1801
|
| **v3.0.29** | Patch release |
|
|
1800
1802
|
| **v3.0.28** | Patch release |
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "matrx-orm"
|
|
3
|
-
version = "3.0.
|
|
3
|
+
version = "3.0.32"
|
|
4
4
|
description = "Async-first PostgreSQL ORM with bidirectional migrations, schema introspection, many-to-many relationships, and built-in state caching. Works with any PostgreSQL database."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
license = { text = "MIT" }
|
|
@@ -1266,7 +1266,7 @@ class Column:
|
|
|
1266
1266
|
)
|
|
1267
1267
|
return self.calc_max_length
|
|
1268
1268
|
|
|
1269
|
-
def to_python_model_field(self):
|
|
1269
|
+
def to_python_model_field(self, forward_ref_tables: set[str] | None = None):
|
|
1270
1270
|
field_options = []
|
|
1271
1271
|
if self.is_primary_key:
|
|
1272
1272
|
field_options.append("primary_key=True")
|
|
@@ -1315,7 +1315,9 @@ class Column:
|
|
|
1315
1315
|
to_schema_arg = ""
|
|
1316
1316
|
if fk_schema and fk_schema != "public":
|
|
1317
1317
|
to_schema_arg = f", to_schema='{fk_schema}'"
|
|
1318
|
-
|
|
1318
|
+
is_self_ref = related_model == self.utils.to_pascal_case(self.table_name)
|
|
1319
|
+
is_forward_ref = forward_ref_tables is not None and related_model in forward_ref_tables
|
|
1320
|
+
if is_self_ref or is_forward_ref:
|
|
1319
1321
|
field_def = f"{self.name} = ForeignKey(to_model='{related_model}', to_column='{self.foreign_key_reference['column']}'{to_schema_arg}, {options_str})"
|
|
1320
1322
|
else:
|
|
1321
1323
|
field_def = f"{self.name} = ForeignKey(to_model={related_model}, to_column='{self.foreign_key_reference['column']}'{to_schema_arg}, {options_str})"
|
|
@@ -361,6 +361,7 @@ def parse_models_file(path: str | Path) -> tuple[dict[str, TableSnapshot], dict[
|
|
|
361
361
|
m2m_config: dict[str, dict[str, str]] = {}
|
|
362
362
|
database: str | None = None
|
|
363
363
|
table_name_override: str | None = None
|
|
364
|
+
db_schema: str | None = None
|
|
364
365
|
|
|
365
366
|
for item in node.body:
|
|
366
367
|
if isinstance(item, (ast.Assign, ast.AnnAssign)):
|
|
@@ -395,6 +396,13 @@ def parse_models_file(path: str | Path) -> tuple[dict[str, TableSnapshot], dict[
|
|
|
395
396
|
pass
|
|
396
397
|
continue
|
|
397
398
|
|
|
399
|
+
if attr_name == "_db_schema":
|
|
400
|
+
try:
|
|
401
|
+
db_schema = ast.literal_eval(value)
|
|
402
|
+
except (ValueError, TypeError):
|
|
403
|
+
pass
|
|
404
|
+
continue
|
|
405
|
+
|
|
398
406
|
if attr_name == "_inverse_foreign_keys":
|
|
399
407
|
try:
|
|
400
408
|
ifk_config = ast.literal_eval(value)
|
|
@@ -416,6 +424,12 @@ def parse_models_file(path: str | Path) -> tuple[dict[str, TableSnapshot], dict[
|
|
|
416
424
|
field_type, kwargs = _parse_field_call(value)
|
|
417
425
|
fields[attr_name] = _kwargs_to_field_snapshot(attr_name, field_type, kwargs)
|
|
418
426
|
|
|
427
|
+
# Skip cross-schema stub models (e.g. Users with _db_schema="auth").
|
|
428
|
+
# They are hardcoded in generate_models() and don't correspond to any
|
|
429
|
+
# introspected table in the target schema.
|
|
430
|
+
if db_schema is not None:
|
|
431
|
+
continue
|
|
432
|
+
|
|
419
433
|
snake_name = table_name_override or _pascal_to_snake(class_name)
|
|
420
434
|
|
|
421
435
|
snapshot = TableSnapshot(
|
|
@@ -451,6 +465,33 @@ def _pascal_to_snake(name: str) -> str:
|
|
|
451
465
|
# Table-to-snapshot converter — extract TableSnapshot from a schema_builder Table
|
|
452
466
|
# ---------------------------------------------------------------------------
|
|
453
467
|
|
|
468
|
+
def _normalize_python_default(value: Any) -> Any:
|
|
469
|
+
"""Apply the same default-value normalization as Column.to_python_model_field().
|
|
470
|
+
|
|
471
|
+
The generator converts raw ``clean_default["python"]`` values before writing
|
|
472
|
+
them into model source code (e.g. the string ``"false"`` becomes the Python
|
|
473
|
+
boolean ``False``). This function mirrors that logic so the snapshot
|
|
474
|
+
produced from a Table object is directly comparable to what the AST parser
|
|
475
|
+
extracts from generated code.
|
|
476
|
+
"""
|
|
477
|
+
if isinstance(value, (bool, int, float, dict, list)):
|
|
478
|
+
return value
|
|
479
|
+
if isinstance(value, str):
|
|
480
|
+
if value == "false":
|
|
481
|
+
return False
|
|
482
|
+
if value == "true":
|
|
483
|
+
return True
|
|
484
|
+
try:
|
|
485
|
+
import ast as _ast
|
|
486
|
+
parsed = _ast.literal_eval(value)
|
|
487
|
+
if isinstance(parsed, (bool, int, float, dict, list)):
|
|
488
|
+
return parsed
|
|
489
|
+
return value
|
|
490
|
+
except (ValueError, SyntaxError):
|
|
491
|
+
return value
|
|
492
|
+
return value
|
|
493
|
+
|
|
494
|
+
|
|
454
495
|
def table_to_snapshot(table: Any) -> TableSnapshot:
|
|
455
496
|
"""Convert a schema_builder.tables.Table into a TableSnapshot."""
|
|
456
497
|
from matrx_orm.schema_builder.common import dt_utils
|
|
@@ -496,7 +537,7 @@ def table_to_snapshot(table: Any) -> TableSnapshot:
|
|
|
496
537
|
if column.clean_default is not None:
|
|
497
538
|
py_default = column.clean_default.get("python")
|
|
498
539
|
if py_default is not None and py_default != "":
|
|
499
|
-
default_val = repr(py_default)
|
|
540
|
+
default_val = repr(_normalize_python_default(py_default))
|
|
500
541
|
|
|
501
542
|
fields[column.name] = FieldSnapshot(
|
|
502
543
|
name=column.name,
|
|
@@ -778,12 +778,62 @@ class Schema:
|
|
|
778
778
|
_database = \"{self.database_project}\"\n"""
|
|
779
779
|
return users_model
|
|
780
780
|
|
|
781
|
-
def
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
781
|
+
def _utils_for_stubs(self):
|
|
782
|
+
return self.utils
|
|
783
|
+
|
|
784
|
+
def _generate_stub_model(self, table_name: str) -> str:
|
|
785
|
+
"""Return a minimal Model stub for *table_name*.
|
|
786
|
+
|
|
787
|
+
If the table was introspected (i.e. exists in ``self.tables``), the
|
|
788
|
+
stub includes the real PK column(s) and their types. Otherwise a
|
|
789
|
+
generic ``id = UUIDField(primary_key=True, null=False)`` is emitted.
|
|
790
|
+
|
|
791
|
+
The stub carries ``_unfetchable = True`` so the ORM never tries to
|
|
792
|
+
query through it (the real table may not be in scope).
|
|
793
|
+
"""
|
|
794
|
+
utils = self._utils_for_stubs()
|
|
795
|
+
pascal_name = utils.to_pascal_case(table_name)
|
|
796
|
+
|
|
797
|
+
if table_name in self.tables:
|
|
798
|
+
table = self.tables[table_name]
|
|
799
|
+
pk_lines = []
|
|
800
|
+
for col in table.columns:
|
|
801
|
+
if col.is_primary_key:
|
|
802
|
+
pk_lines.append(
|
|
803
|
+
f" {col.name} = {col.python_field_type}"
|
|
804
|
+
f"(primary_key=True, null=False)"
|
|
805
|
+
)
|
|
806
|
+
if not pk_lines:
|
|
807
|
+
pk_lines = [" id = UUIDField(primary_key=True, null=False)"]
|
|
808
|
+
else:
|
|
809
|
+
pk_lines = [" id = UUIDField(primary_key=True, null=False)"]
|
|
810
|
+
|
|
811
|
+
pk_block = "\n".join(pk_lines)
|
|
812
|
+
return (
|
|
813
|
+
f"class {pascal_name}(Model):\n"
|
|
814
|
+
f"{pk_block}\n"
|
|
815
|
+
f" _table_name = \"{table_name}\"\n"
|
|
816
|
+
f" _database = \"{self.database_project}\"\n"
|
|
817
|
+
f" _unfetchable = True\n"
|
|
818
|
+
)
|
|
819
|
+
|
|
820
|
+
def get_string_model_registry(
|
|
821
|
+
self,
|
|
822
|
+
sorted_tables: list[str],
|
|
823
|
+
stub_model_names: set[str] | None = None,
|
|
824
|
+
) -> str:
|
|
825
|
+
# Register every model class defined in the file: included tables,
|
|
826
|
+
# stub models for FK dependencies, and the Users stub.
|
|
786
827
|
all_models = [self.tables[t].name_pascal for t in sorted_tables]
|
|
828
|
+
if stub_model_names:
|
|
829
|
+
utils = self._utils_for_stubs()
|
|
830
|
+
for sn in sorted(stub_model_names):
|
|
831
|
+
pascal = (
|
|
832
|
+
self.tables[sn].name_pascal
|
|
833
|
+
if sn in self.tables
|
|
834
|
+
else utils.to_pascal_case(sn)
|
|
835
|
+
)
|
|
836
|
+
all_models.append(pascal)
|
|
787
837
|
all_models.append("Users") # Users stub is always generated
|
|
788
838
|
|
|
789
839
|
model_registry_string = (
|
|
@@ -842,9 +892,60 @@ class Schema:
|
|
|
842
892
|
py_structure = [self.get_string_user_model()]
|
|
843
893
|
all_field_types = {"UUIDField", "CharField", "Model"}
|
|
844
894
|
|
|
895
|
+
# --- Stub generation for FK targets outside the filtered set ----------
|
|
896
|
+
# When include_tables / exclude_tables is active, included tables may
|
|
897
|
+
# reference models that aren't being generated. We emit minimal stub
|
|
898
|
+
# classes for those targets so FK declarations resolve without NameError
|
|
899
|
+
# and resolve_model() can find them in the registry at runtime.
|
|
900
|
+
sorted_set = set(sorted_tables)
|
|
901
|
+
_stub_model_names: set[str] = set()
|
|
902
|
+
|
|
903
|
+
if self._include_tables is not None or self._exclude_tables is not None:
|
|
904
|
+
for table_name in sorted_tables:
|
|
905
|
+
table = self.tables[table_name]
|
|
906
|
+
for col in table.columns:
|
|
907
|
+
if col.foreign_key_reference:
|
|
908
|
+
target_snake = col.foreign_key_reference["table"]
|
|
909
|
+
fk_schema = col.foreign_key_reference.get("schema")
|
|
910
|
+
if fk_schema and fk_schema != "public":
|
|
911
|
+
continue # cross-schema (e.g. auth.users) — stub already exists
|
|
912
|
+
if target_snake not in sorted_set:
|
|
913
|
+
_stub_model_names.add(target_snake)
|
|
914
|
+
|
|
915
|
+
for stub_table_name in sorted(_stub_model_names):
|
|
916
|
+
py_structure.append(
|
|
917
|
+
self._generate_stub_model(stub_table_name)
|
|
918
|
+
)
|
|
919
|
+
|
|
920
|
+
# --- Build position map for forward-reference detection ---------------
|
|
921
|
+
# Stubs are defined before any included table (position -1 conceptually),
|
|
922
|
+
# so they never need forward references.
|
|
923
|
+
_table_positions = {name: i for i, name in enumerate(sorted_tables)}
|
|
924
|
+
_defined_stubs = {
|
|
925
|
+
self.tables[s].name_pascal if s in self.tables
|
|
926
|
+
else self._utils_for_stubs().to_pascal_case(s)
|
|
927
|
+
for s in _stub_model_names
|
|
928
|
+
}
|
|
929
|
+
|
|
845
930
|
for table_name in sorted_tables:
|
|
846
931
|
table = self.tables[table_name]
|
|
847
|
-
|
|
932
|
+
my_pos = _table_positions[table_name]
|
|
933
|
+
forward_ref_tables: set[str] = set()
|
|
934
|
+
for col in table.columns:
|
|
935
|
+
if col.foreign_key_reference:
|
|
936
|
+
target_snake = col.foreign_key_reference["table"]
|
|
937
|
+
target_pos = _table_positions.get(target_snake)
|
|
938
|
+
if target_pos is not None and target_pos > my_pos:
|
|
939
|
+
forward_ref_tables.add(
|
|
940
|
+
table.utils.to_pascal_case(target_snake)
|
|
941
|
+
)
|
|
942
|
+
elif target_pos is None:
|
|
943
|
+
target_pascal = table.utils.to_pascal_case(target_snake)
|
|
944
|
+
if target_pascal != "Users" and target_pascal not in _defined_stubs:
|
|
945
|
+
forward_ref_tables.add(target_pascal)
|
|
946
|
+
py_table_entry = table.to_python_model(
|
|
947
|
+
forward_ref_tables=forward_ref_tables or None
|
|
948
|
+
)
|
|
848
949
|
py_structure.append(py_table_entry)
|
|
849
950
|
all_field_types.update(table.unique_field_types)
|
|
850
951
|
|
|
@@ -900,7 +1001,9 @@ class Schema:
|
|
|
900
1001
|
color="cyan",
|
|
901
1002
|
)
|
|
902
1003
|
|
|
903
|
-
py_structure.append(
|
|
1004
|
+
py_structure.append(
|
|
1005
|
+
self.get_string_model_registry(sorted_tables, _stub_model_names)
|
|
1006
|
+
)
|
|
904
1007
|
|
|
905
1008
|
main_code = "\n".join(py_structure)
|
|
906
1009
|
additional_code = "\n".join(py_manager_structure)
|
|
@@ -1079,9 +1079,15 @@ class Table:
|
|
|
1079
1079
|
}
|
|
1080
1080
|
return m2m_config
|
|
1081
1081
|
|
|
1082
|
-
def to_python_model(self):
|
|
1082
|
+
def to_python_model(self, forward_ref_tables: set[str] | None = None):
|
|
1083
1083
|
"""
|
|
1084
1084
|
Builds the Python class model string with dynamic foreign keys.
|
|
1085
|
+
|
|
1086
|
+
*forward_ref_tables* is an optional set of PascalCase model names that
|
|
1087
|
+
will be defined later in the file. FKs targeting these models are
|
|
1088
|
+
emitted as string forward references (``to_model='Foo'``) instead of
|
|
1089
|
+
bare class references (``to_model=Foo``), avoiding ``NameError`` from
|
|
1090
|
+
circular FK dependencies.
|
|
1085
1091
|
"""
|
|
1086
1092
|
py_fields = []
|
|
1087
1093
|
self.unique_field_types = set()
|
|
@@ -1090,7 +1096,7 @@ class Table:
|
|
|
1090
1096
|
|
|
1091
1097
|
# Process regular fields for the model
|
|
1092
1098
|
for column in self.columns:
|
|
1093
|
-
py_field = column.to_python_model_field()
|
|
1099
|
+
py_field = column.to_python_model_field(forward_ref_tables=forward_ref_tables)
|
|
1094
1100
|
py_fields.append(py_field)
|
|
1095
1101
|
|
|
1096
1102
|
if column.foreign_key_reference:
|
|
@@ -90,6 +90,25 @@ generate:
|
|
|
90
90
|
# This dramatically reduces git noise on large schemas. Default: false.
|
|
91
91
|
# skip_unchanged_managers: true
|
|
92
92
|
manager_flags:
|
|
93
|
+
# models_module_path — the Python import path used in each generated
|
|
94
|
+
# manager file to import the model class from models.py.
|
|
95
|
+
#
|
|
96
|
+
# Default: "db.models" → from db.models import MyModel
|
|
97
|
+
#
|
|
98
|
+
# Override this when the generated db/ package is not at the root of your
|
|
99
|
+
# Python path. For example, if your project is structured as a package:
|
|
100
|
+
#
|
|
101
|
+
# mypackage/
|
|
102
|
+
# db/
|
|
103
|
+
# models.py
|
|
104
|
+
# managers/
|
|
105
|
+
#
|
|
106
|
+
# and you import things as `from mypackage.db.models import ...`, set:
|
|
107
|
+
#
|
|
108
|
+
# models_module_path: "mypackage.db.models"
|
|
109
|
+
#
|
|
110
|
+
# models_module_path: "db.models"
|
|
111
|
+
#
|
|
93
112
|
include_core_relations: true # FK/IFK fetch methods (load_by_*, fetch_fk, fetch_ifk)
|
|
94
113
|
include_filter_fields: true # filter_by_* methods for indexed/common lookup fields
|
|
95
114
|
include_active_relations: false # active-record style relation traversal
|
|
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
|
{matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/python_sql/table_detailed_relationships.py
RENAMED
|
File without changes
|
{matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/python_sql/table_typescript_relationship.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/schema_builder/helpers/base_generators.py
RENAMED
|
File without changes
|
{matrx_orm-3.0.30 → matrx_orm-3.0.32}/src/matrx_orm/schema_builder/helpers/entity_generators.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
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
|
{matrx_orm-3.0.30 → matrx_orm-3.0.32}/tests/sample_project_desktop/client_supabase_example.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|