matrx-orm 3.0.30__tar.gz → 3.0.31__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.
Files changed (187) hide show
  1. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/PKG-INFO +2 -1
  2. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/README.md +1 -0
  3. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/pyproject.toml +1 -1
  4. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/schema_builder/columns.py +4 -2
  5. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/schema_builder/diff_preview.py +42 -1
  6. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/schema_builder/schema.py +18 -1
  7. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/schema_builder/tables.py +8 -2
  8. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/.arman/pending/versioning/INITIAL.md +0 -0
  9. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/.env.example +0 -0
  10. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/.github/workflows/publish.yml +0 -0
  11. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/.gitignore +0 -0
  12. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/.python-version +0 -0
  13. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/.vscode/settings.json +0 -0
  14. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/CLAUDE.md +0 -0
  15. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/DESKTOP-API-INTEGRATION.md +0 -0
  16. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/MIGRATIONS.md +0 -0
  17. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/MODULE_README.md +0 -0
  18. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/RESERVED_NAMES.md +0 -0
  19. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/TASKS-TEMPLATE.md +0 -0
  20. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/TASKS.md +0 -0
  21. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/TRANSACTION_POOLER_PLAN.MD +0 -0
  22. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/WRITE-QUEUE-UPGRADE.md +0 -0
  23. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/database/orm/extended/managers/ai_model_base.py +0 -0
  24. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/docs/migrations.md +0 -0
  25. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/extended_jan5_backup.py +0 -0
  26. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/main.py +0 -0
  27. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/release.sh +0 -0
  28. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/scripts/git-branches.sh +0 -0
  29. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/scripts/publish.sh +0 -0
  30. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/scripts/release.sh +0 -0
  31. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/MODULE_README.md +0 -0
  32. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/MODULE_README.md +0 -0
  33. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/__init__.py +0 -0
  34. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/adapters/MODULE_README.md +0 -0
  35. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/adapters/__init__.py +0 -0
  36. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/adapters/async_postgresql.py +0 -0
  37. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/adapters/base_adapter.py +0 -0
  38. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/adapters/postgresql.py +0 -0
  39. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/adapters/postgrest_client_adapter.py +0 -0
  40. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/adapters/supabase_adapter.py +0 -0
  41. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/api/__init__.py +0 -0
  42. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/api/auth.py +0 -0
  43. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/api/config.py +0 -0
  44. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/api/handlers.py +0 -0
  45. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/api/protocol.py +0 -0
  46. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/api/server.py +0 -0
  47. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/client/MODULE_README.md +0 -0
  48. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/client/__init__.py +0 -0
  49. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/client/postgres_connection.py +0 -0
  50. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/client/postgrest.py +0 -0
  51. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/client/supabase_auth.py +0 -0
  52. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/client/supabase_config.py +0 -0
  53. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/client/supabase_manager.py +0 -0
  54. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/core/EXTENDED-TASK.md +0 -0
  55. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/core/MODULE_README.md +0 -0
  56. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/core/RELATIONS-TASKS.md +0 -0
  57. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/core/TASKS.md +0 -0
  58. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/core/__init__.py +0 -0
  59. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/core/async_db_manager.py +0 -0
  60. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/core/base.py +0 -0
  61. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/core/config.py +0 -0
  62. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/core/expressions.py +0 -0
  63. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/core/extended.py +0 -0
  64. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/core/fields.py +0 -0
  65. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/core/model_dto.py +0 -0
  66. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/core/model_view.py +0 -0
  67. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/core/paginator.py +0 -0
  68. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/core/pydantic_bridge.py +0 -0
  69. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/core/registry.py +0 -0
  70. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/core/relations.py +0 -0
  71. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/core/signals.py +0 -0
  72. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/core/transaction.py +0 -0
  73. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/core/types.py +0 -0
  74. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/core/write_queue.py +0 -0
  75. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/error_handling.py +0 -0
  76. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/exceptions.py +0 -0
  77. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/extended/__init__.py +0 -0
  78. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/extended/app_error_handler.py +0 -0
  79. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/middleware/__init__.py +0 -0
  80. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/middleware/base.py +0 -0
  81. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/migrations/MODULE_README.md +0 -0
  82. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/migrations/__init__.py +0 -0
  83. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/migrations/cli.py +0 -0
  84. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/migrations/ddl.py +0 -0
  85. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/migrations/diff.py +0 -0
  86. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/migrations/executor.py +0 -0
  87. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/migrations/integration.py +0 -0
  88. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/migrations/loader.py +0 -0
  89. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/migrations/operations.py +0 -0
  90. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/migrations/state.py +0 -0
  91. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/migrations/table_filter.py +0 -0
  92. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/operations/MODULE_README.md +0 -0
  93. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/operations/__init__.py +0 -0
  94. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/operations/create.py +0 -0
  95. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/operations/delete.py +0 -0
  96. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/operations/read.py +0 -0
  97. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/operations/update.py +0 -0
  98. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/py.typed +0 -0
  99. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/python_sql/MODULE_README.md +0 -0
  100. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/python_sql/__init__.py +0 -0
  101. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/python_sql/db_objects.py +0 -0
  102. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/python_sql/table_detailed_relationships.py +0 -0
  103. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/python_sql/table_typescript_relationship.py +0 -0
  104. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/query/MODULE_README.md +0 -0
  105. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/query/__init__.py +0 -0
  106. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/query/builder.py +0 -0
  107. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/query/executor.py +0 -0
  108. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/schema_builder/MODULE_README.md +0 -0
  109. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/schema_builder/__init__.py +0 -0
  110. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/schema_builder/code_handler.py +0 -0
  111. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/schema_builder/common.py +0 -0
  112. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/schema_builder/generator.py +0 -0
  113. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/schema_builder/helpers/__init__.py +0 -0
  114. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/schema_builder/helpers/base_generators.py +0 -0
  115. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/schema_builder/helpers/entity_generators.py +0 -0
  116. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/schema_builder/helpers/git_checker.py +0 -0
  117. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/schema_builder/relationships.py +0 -0
  118. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/schema_builder/runner.py +0 -0
  119. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/schema_builder/schema_manager.py +0 -0
  120. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/schema_builder/views.py +0 -0
  121. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/sql_executor/MODULE_README.md +0 -0
  122. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/sql_executor/__init__.py +0 -0
  123. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/sql_executor/executor.py +0 -0
  124. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/sql_executor/queries.py +0 -0
  125. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/sql_executor/registry.py +0 -0
  126. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/sql_executor/types.py +0 -0
  127. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/sql_executor/utils.py +0 -0
  128. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/state.py +0 -0
  129. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/utils/__init__.py +0 -0
  130. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/utils/sql_utils.py +0 -0
  131. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/src/matrx_orm/utils/type_converters.py +0 -0
  132. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/tests/MODULE_README.md +0 -0
  133. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/tests/__init__.py +0 -0
  134. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/tests/conftest.py +0 -0
  135. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/tests/level1/MODULE_README.md +0 -0
  136. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/tests/level1/__init__.py +0 -0
  137. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/tests/level1/test_api_auth.py +0 -0
  138. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/tests/level1/test_api_config.py +0 -0
  139. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/tests/level1/test_api_handlers.py +0 -0
  140. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/tests/level1/test_api_protocol.py +0 -0
  141. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/tests/level1/test_config.py +0 -0
  142. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/tests/level1/test_ddl_generator.py +0 -0
  143. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/tests/level1/test_exceptions.py +0 -0
  144. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/tests/level1/test_fields.py +0 -0
  145. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/tests/level1/test_migration_diff_types.py +0 -0
  146. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/tests/level1/test_migration_loader.py +0 -0
  147. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/tests/level1/test_model_instance.py +0 -0
  148. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/tests/level1/test_model_meta.py +0 -0
  149. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/tests/level1/test_postgrest_filters.py +0 -0
  150. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/tests/level1/test_query_builder.py +0 -0
  151. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/tests/level1/test_query_executor_sql.py +0 -0
  152. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/tests/level1/test_registry.py +0 -0
  153. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/tests/level1/test_relations.py +0 -0
  154. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/tests/level1/test_state_cache.py +0 -0
  155. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/tests/level1/test_supabase_auth.py +0 -0
  156. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/tests/level1/test_supabase_config.py +0 -0
  157. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/tests/level2/MODULE_README.md +0 -0
  158. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/tests/level2/__init__.py +0 -0
  159. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/tests/level2/conftest.py +0 -0
  160. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/tests/level2/test_bulk_ops.py +0 -0
  161. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/tests/level2/test_cache_integration.py +0 -0
  162. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/tests/level2/test_crud.py +0 -0
  163. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/tests/level2/test_foreign_keys.py +0 -0
  164. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/tests/level2/test_m2m.py +0 -0
  165. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/tests/level2/test_manager.py +0 -0
  166. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/tests/level2/test_migrations_live.py +0 -0
  167. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/tests/level2/test_query_execution.py +0 -0
  168. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/tests/level2/test_schema_diff.py +0 -0
  169. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/tests/sample_project/.env.example +0 -0
  170. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/tests/sample_project/README.md +0 -0
  171. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/tests/sample_project/__init__.py +0 -0
  172. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/tests/sample_project/generate.py +0 -0
  173. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/tests/sample_project/generated/.gitkeep +0 -0
  174. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/tests/sample_project/matrx_orm.yaml +0 -0
  175. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/tests/sample_project/test_schema_generation.py +0 -0
  176. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/tests/sample_project_desktop/.env.example +0 -0
  177. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/tests/sample_project_desktop/README.md +0 -0
  178. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/tests/sample_project_desktop/__init__.py +0 -0
  179. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/tests/sample_project_desktop/client_example.py +0 -0
  180. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/tests/sample_project_desktop/client_example.ts +0 -0
  181. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/tests/sample_project_desktop/client_supabase_example.py +0 -0
  182. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/tests/sample_project_desktop/server.py +0 -0
  183. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/tests/schema/entity_tests.py +0 -0
  184. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/tests/schema/test_base_generation.py +0 -0
  185. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/tests/schema/test_generate_schema.py +0 -0
  186. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/tests/test_model_cls_refactor.py +0 -0
  187. {matrx_orm-3.0.30 → matrx_orm-3.0.31}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: matrx-orm
3
- Version: 3.0.30
3
+ Version: 3.0.31
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,7 @@ 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.31** | Patch release |
1841
1842
  | **v3.0.30** | Patch release |
1842
1843
  | **v3.0.29** | Patch release |
1843
1844
  | **v3.0.28** | Patch release |
@@ -1795,6 +1795,7 @@ 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.31** | Patch release |
1798
1799
  | **v3.0.30** | Patch release |
1799
1800
  | **v3.0.29** | Patch release |
1800
1801
  | **v3.0.28** | Patch release |
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "matrx-orm"
3
- version = "3.0.30"
3
+ version = "3.0.31"
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
- if related_model == self.utils.to_pascal_case(self.table_name):
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,
@@ -842,9 +842,26 @@ class Schema:
842
842
  py_structure = [self.get_string_user_model()]
843
843
  all_field_types = {"UUIDField", "CharField", "Model"}
844
844
 
845
+ # Build a position map so each table knows which models are defined
846
+ # after it in the file. FKs to those models must use string forward
847
+ # references to avoid NameError from circular dependencies.
848
+ _table_positions = {name: i for i, name in enumerate(sorted_tables)}
849
+
845
850
  for table_name in sorted_tables:
846
851
  table = self.tables[table_name]
847
- py_table_entry = table.to_python_model()
852
+ my_pos = _table_positions[table_name]
853
+ forward_ref_tables: set[str] = set()
854
+ for col in table.columns:
855
+ if col.foreign_key_reference:
856
+ target_snake = col.foreign_key_reference["table"]
857
+ target_pos = _table_positions.get(target_snake)
858
+ if target_pos is None or target_pos > my_pos:
859
+ target_pascal = table.utils.to_pascal_case(target_snake)
860
+ if target_pascal != "Users":
861
+ forward_ref_tables.add(target_pascal)
862
+ py_table_entry = table.to_python_model(
863
+ forward_ref_tables=forward_ref_tables or None
864
+ )
848
865
  py_structure.append(py_table_entry)
849
866
  all_field_types.update(table.unique_field_types)
850
867
 
@@ -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:
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes