diff --git a/.check_expression_baseline.json b/.check_expression_baseline.json new file mode 100644 index 00000000..9701bfae --- /dev/null +++ b/.check_expression_baseline.json @@ -0,0 +1,158 @@ +{ + "entries": { + "1ed29036faf46a82": 2, + "27df13aa97e8f397": 2, + "3ed8ec0dc8194acc": 4, + "558ff589c7816db1": 1, + "585e34e100bdd398": 2, + "5ae1f677effad792": 1, + "93794eba1e84abdf": 1, + "96b19532f33d13aa": 1, + "acf9357340ec4b2e": 1, + "b6b323654639d84e": 1, + "b865f866dd599e89": 1, + "c8cba7dd7eafe9d9": 2, + "d3b3e3d27e7e76ad": 2, + "e62ffd51c027b61a": 4, + "edb1d2cceabc1515": 1, + "f1167066a3660d0e": 1 + }, + "findings": [ + { + "found": "if_not_exists: Optional[bool]", + "path": "src/rhosocial/activerecord/backend/impl/mysql/expression/alter_column.py", + "rule": "ED-10.2" + }, + { + "found": "invisible: Optional[bool]", + "path": "src/rhosocial/activerecord/backend/impl/mysql/expression/column.py", + "rule": "ED-10.2" + }, + { + "found": "invisible: Optional[bool]", + "path": "src/rhosocial/activerecord/backend/impl/mysql/expression/column.py", + "rule": "ED-10.2" + }, + { + "found": "kwargs: Any", + "path": "src/rhosocial/activerecord/backend/impl/mysql/expression/json.py", + "rule": "ED-KWARGS" + }, + { + "found": "getattr(action, \"if_not_exists\", None)", + "path": "src/rhosocial/activerecord/backend/impl/mysql/mixins/ddl_column.py", + "rule": "ED-11.2" + }, + { + "found": "getattr(action, \"after\", None)", + "path": "src/rhosocial/activerecord/backend/impl/mysql/mixins/ddl_column.py", + "rule": "ED-11.2" + }, + { + "found": "getattr(action, \"if_exists\", None)", + "path": "src/rhosocial/activerecord/backend/impl/mysql/mixins/ddl_column.py", + "rule": "ED-11.2" + }, + { + "found": "getattr(action, \"if_exists\", None)", + "path": "src/rhosocial/activerecord/backend/impl/mysql/mixins/ddl_column.py", + "rule": "ED-11.2" + }, + { + "found": "getattr(action.operation, \"value\", None)", + "path": "src/rhosocial/activerecord/backend/impl/mysql/mixins/ddl_column.py", + "rule": "ED-11.2" + }, + { + "found": "getattr(action, \"new_value\", None)", + "path": "src/rhosocial/activerecord/backend/impl/mysql/mixins/ddl_column.py", + "rule": "ED-11.2" + }, + { + "found": "getattr(expr, \"table_options\", None)", + "path": "src/rhosocial/activerecord/backend/impl/mysql/mixins/ddl_table.py", + "rule": "ED-11.2" + }, + { + "found": "getattr(expr, \"table_options\", None)", + "path": "src/rhosocial/activerecord/backend/impl/mysql/mixins/ddl_table.py", + "rule": "ED-11.2" + }, + { + "found": "getattr(table_options, \"comment\", None)", + "path": "src/rhosocial/activerecord/backend/impl/mysql/mixins/ddl_table.py", + "rule": "ED-11.2" + }, + { + "found": "getattr(expr, \"options\", None)", + "path": "src/rhosocial/activerecord/backend/impl/mysql/mixins/maintenance.py", + "rule": "ED-11.2" + }, + { + "found": "getattr(expr, \"option\", None)", + "path": "src/rhosocial/activerecord/backend/impl/mysql/mixins/maintenance.py", + "rule": "ED-11.2" + }, + { + "found": "getattr(expr, \"options\", None)", + "path": "src/rhosocial/activerecord/backend/impl/mysql/mixins/maintenance.py", + "rule": "ED-11.2" + }, + { + "found": "getattr(expr, \"subpartition_by\", None)", + "path": "src/rhosocial/activerecord/backend/impl/mysql/mixins/partition.py", + "rule": "ED-11.2" + }, + { + "found": "getattr(expr, \"partitions\", [])", + "path": "src/rhosocial/activerecord/backend/impl/mysql/mixins/partition.py", + "rule": "ED-11.2" + }, + { + "found": "getattr(expr, \"subpartition_by\", None)", + "path": "src/rhosocial/activerecord/backend/impl/mysql/mixins/partition.py", + "rule": "ED-11.2" + }, + { + "found": "getattr(expr, \"partitions\", [])", + "path": "src/rhosocial/activerecord/backend/impl/mysql/mixins/partition.py", + "rule": "ED-11.2" + }, + { + "found": "getattr(expr, \"subpartition_by\", None)", + "path": "src/rhosocial/activerecord/backend/impl/mysql/mixins/partition.py", + "rule": "ED-11.2" + }, + { + "found": "getattr(expr, \"partitions\", [])", + "path": "src/rhosocial/activerecord/backend/impl/mysql/mixins/partition.py", + "rule": "ED-11.2" + }, + { + "found": "getattr(expr, \"subpartition_by\", None)", + "path": "src/rhosocial/activerecord/backend/impl/mysql/mixins/partition.py", + "rule": "ED-11.2" + }, + { + "found": "getattr(expr, \"partitions\", [])", + "path": "src/rhosocial/activerecord/backend/impl/mysql/mixins/partition.py", + "rule": "ED-11.2" + }, + { + "found": "getattr(expr, \"partitions_count\", None)", + "path": "src/rhosocial/activerecord/backend/impl/mysql/mixins/partition.py", + "rule": "ED-11.2" + }, + { + "found": "getattr(expr, \"partitions_count\", None)", + "path": "src/rhosocial/activerecord/backend/impl/mysql/mixins/partition.py", + "rule": "ED-11.2" + }, + { + "found": "getattr(definition, \"subpartition_definitions\", None)", + "path": "src/rhosocial/activerecord/backend/impl/mysql/mixins/partition.py", + "rule": "ED-11.2" + } + ], + "format": 1 +} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index cfa10652..53b73460 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -52,8 +52,8 @@ jobs: - name: Install activerecord and testsuite run: | - pip install "rhosocial-activerecord @ git+https://github.com/rhosocial/python-activerecord.git@feature/error-taxonomy" # NOSONAR - pip install "rhosocial-activerecord-testsuite @ git+https://github.com/rhosocial/python-activerecord-testsuite.git@feature/error-taxonomy" # NOSONAR + pip install "rhosocial-activerecord @ git+https://github.com/rhosocial/python-activerecord.git@release/v1.0.0.dev30" # NOSONAR + pip install "rhosocial-activerecord-testsuite @ git+https://github.com/rhosocial/python-activerecord-testsuite.git@release/v1.0.0.dev17" # NOSONAR - name: Install dependencies run: | @@ -247,8 +247,8 @@ jobs: - name: Install activerecord and testsuite run: | - pip install "rhosocial-activerecord @ git+https://github.com/rhosocial/python-activerecord.git@feature/error-taxonomy" # NOSONAR - pip install "rhosocial-activerecord-testsuite @ git+https://github.com/rhosocial/python-activerecord-testsuite.git@feature/error-taxonomy" # NOSONAR + pip install "rhosocial-activerecord @ git+https://github.com/rhosocial/python-activerecord.git@release/v1.0.0.dev30" # NOSONAR + pip install "rhosocial-activerecord-testsuite @ git+https://github.com/rhosocial/python-activerecord-testsuite.git@release/v1.0.0.dev17" # NOSONAR - name: Install dependencies run: | @@ -354,8 +354,8 @@ jobs: - name: Install activerecord and testsuite run: | - pip install "rhosocial-activerecord @ git+https://github.com/rhosocial/python-activerecord.git@feature/error-taxonomy" # NOSONAR - pip install "rhosocial-activerecord-testsuite @ git+https://github.com/rhosocial/python-activerecord-testsuite.git@feature/error-taxonomy" # NOSONAR + pip install "rhosocial-activerecord @ git+https://github.com/rhosocial/python-activerecord.git@release/v1.0.0.dev30" # NOSONAR + pip install "rhosocial-activerecord-testsuite @ git+https://github.com/rhosocial/python-activerecord-testsuite.git@release/v1.0.0.dev17" # NOSONAR - name: Install dependencies run: | diff --git a/tests/providers/basic_connection.py b/tests/providers/basic_connection.py index a35a5121..b2698f01 100644 --- a/tests/providers/basic_connection.py +++ b/tests/providers/basic_connection.py @@ -21,7 +21,10 @@ class SyncTestUser(ActiveRecord): """Sync test user model for connection pool tests.""" - __table_name__ = "test_users" + @classmethod + def table_name(cls): + return "test_users" + id: Optional[int] = None name: str email: str @@ -30,7 +33,10 @@ class SyncTestUser(ActiveRecord): class AsyncTestUser(AsyncActiveRecord): """Async test user model for connection pool tests.""" - __table_name__ = "test_users" + @classmethod + def table_name(cls): + return "test_users" + id: Optional[int] = None name: str email: str diff --git a/tests/providers/partition.py b/tests/providers/partition.py index 61aa47df..9fee58e7 100644 --- a/tests/providers/partition.py +++ b/tests/providers/partition.py @@ -231,7 +231,10 @@ def _event_model(self, backend): table_name = self.TABLE_NAME class PartitionEvent(ActiveRecord): - __table_name__ = table_name + @classmethod + def table_name(cls): + return table_name + __backend__ = backend c: ClassVar[FieldProxy] = FieldProxy() @@ -247,7 +250,10 @@ def _async_event_model(self, backend): table_name = self.TABLE_NAME class AsyncPartitionEvent(AsyncActiveRecord): - __table_name__ = table_name + @classmethod + def table_name(cls): + return table_name + __backend__ = backend c: ClassVar[FieldProxy] = FieldProxy() diff --git a/tests/providers/query_connection.py b/tests/providers/query_connection.py index b445d27c..56904b48 100644 --- a/tests/providers/query_connection.py +++ b/tests/providers/query_connection.py @@ -21,7 +21,10 @@ class SyncQueryTestUser(ActiveRecord): """Sync test user model for query connection pool tests.""" - __table_name__ = "test_users" + @classmethod + def table_name(cls): + return "test_users" + id: Optional[int] = None name: str email: str @@ -30,7 +33,10 @@ class SyncQueryTestUser(ActiveRecord): class AsyncQueryTestUser(AsyncActiveRecord): """Async test user model for query connection pool tests.""" - __table_name__ = "test_users" + @classmethod + def table_name(cls): + return "test_users" + id: Optional[int] = None name: str email: str diff --git a/tests/rhosocial/activerecord_mysql_test/feature/backend/ddl/test_ddl_source_collection.py b/tests/rhosocial/activerecord_mysql_test/feature/backend/ddl/test_ddl_source_collection.py index 089a9885..e220ffbc 100644 --- a/tests/rhosocial/activerecord_mysql_test/feature/backend/ddl/test_ddl_source_collection.py +++ b/tests/rhosocial/activerecord_mysql_test/feature/backend/ddl/test_ddl_source_collection.py @@ -176,8 +176,14 @@ def apply(cls, new_class, field_name, annotation, metadata): class DDLDeclarations: - __table_name__ = "ddl_source_orders" - __primary_key__ = ("tenant_key", "order_key") + @classmethod + def table_name(cls): + return "ddl_source_orders" + + @classmethod + def primary_key(cls): + return ("tenant_key", "order_key") + __table_constraints__ = TABLE_CONSTRAINTS __table_indexes__ = TABLE_INDEXES _feature_handlers = [BackendColumnOptionsHandler] @@ -243,8 +249,13 @@ class AsyncDDLSource(DDLDeclarations, AsyncActiveRecord): class SingleKeyDeclarations: - __table_name__ = "ddl_source_single_key" - __primary_key__ = "record_pk" + @classmethod + def table_name(cls): + return "ddl_source_single_key" + + @classmethod + def primary_key(cls): + return "record_pk" record_id: Annotated[ int, diff --git a/tests/rhosocial/activerecord_mysql_test/feature/backend/ddl/test_derived_ddl_inline_index.py b/tests/rhosocial/activerecord_mysql_test/feature/backend/ddl/test_derived_ddl_inline_index.py index e003af99..1da849f9 100644 --- a/tests/rhosocial/activerecord_mysql_test/feature/backend/ddl/test_derived_ddl_inline_index.py +++ b/tests/rhosocial/activerecord_mysql_test/feature/backend/ddl/test_derived_ddl_inline_index.py @@ -22,7 +22,9 @@ class Indexed(ActiveRecord): - __table_name__ = "indexed" + @classmethod + def table_name(cls): + return "indexed" id: int email: Annotated[str, UseIndex("idx_indexed_email", unique=True)] @@ -36,7 +38,7 @@ def _create_indexed_table(): dialect = mysql_dialect() return CreateTableStatement( dialect, - Table(dialect, Indexed.__table_name__), + Table(dialect, Indexed.table_name()), columns=[ ColumnDefinition(dialect, "id", IntegerType(dialect)), ColumnDefinition(dialect, "email", VarCharType(dialect, 255)), diff --git a/tests/rhosocial/activerecord_mysql_test/feature/backend/test_async_concurrency.py b/tests/rhosocial/activerecord_mysql_test/feature/backend/test_async_concurrency.py index 7e446075..46a9a37d 100644 --- a/tests/rhosocial/activerecord_mysql_test/feature/backend/test_async_concurrency.py +++ b/tests/rhosocial/activerecord_mysql_test/feature/backend/test_async_concurrency.py @@ -43,7 +43,10 @@ class ConcurrentUser(AsyncActiveRecord): """User model for concurrency testing.""" - __table_name__ = "concurrent_users" + @classmethod + def table_name(cls): + return "concurrent_users" + c: ClassVar[FieldProxy] = FieldProxy() id: Optional[int] = None @@ -56,7 +59,10 @@ class ConcurrentUser(AsyncActiveRecord): class ConcurrentTask(AsyncActiveRecord): """Task model for concurrency testing with status tracking.""" - __table_name__ = "concurrent_tasks" + @classmethod + def table_name(cls): + return "concurrent_tasks" + c: ClassVar[FieldProxy] = FieldProxy() id: Optional[int] = None @@ -273,7 +279,10 @@ async def isolated_worker_task(task_id: int): # Configure a task-specific model class class WorkerUser(AsyncActiveRecord): - __table_name__ = "concurrent_users" + @classmethod + def table_name(cls): + return "concurrent_users" + c: ClassVar[FieldProxy] = FieldProxy() id: Optional[int] = None username: str @@ -360,7 +369,10 @@ async def transaction_task(task_id: int, should_commit: bool): await backend.connect() class TxUser(AsyncActiveRecord): - __table_name__ = "concurrent_users" + @classmethod + def table_name(cls): + return "concurrent_users" + c: ClassVar[FieldProxy] = FieldProxy() id: Optional[int] = None username: str @@ -461,7 +473,10 @@ async def test_sequential_vs_concurrent_comparison(mysql_config): await shared_backend.connect() class SharedUser(AsyncActiveRecord): - __table_name__ = "concurrent_users" + @classmethod + def table_name(cls): + return "concurrent_users" + c: ClassVar[FieldProxy] = FieldProxy() id: Optional[int] = None username: str @@ -492,7 +507,10 @@ async def concurrent_insert(task_id: int): try: class ConcurrentUser(AsyncActiveRecord): - __table_name__ = "concurrent_users" + @classmethod + def table_name(cls): + return "concurrent_users" + c: ClassVar[FieldProxy] = FieldProxy() id: Optional[int] = None username: str @@ -577,7 +595,10 @@ async def safe_concurrent_task(task_id: int): try: class SafeUser(AsyncActiveRecord): - __table_name__ = "concurrent_users" + @classmethod + def table_name(cls): + return "concurrent_users" + c: ClassVar[FieldProxy] = FieldProxy() id: Optional[int] = None username: str diff --git a/tests/rhosocial/activerecord_mysql_test/feature/backend/test_mysql_ddl_improvements.py b/tests/rhosocial/activerecord_mysql_test/feature/backend/test_mysql_ddl_improvements.py index c181ef0a..1b98e1d7 100644 --- a/tests/rhosocial/activerecord_mysql_test/feature/backend/test_mysql_ddl_improvements.py +++ b/tests/rhosocial/activerecord_mysql_test/feature/backend/test_mysql_ddl_improvements.py @@ -134,7 +134,9 @@ def test_drop_schema_supported(self): class InheritedTable(ActiveRecord): - __table_name__ = "inherited" + @classmethod + def table_name(cls): + return "inherited" id: int @@ -144,7 +146,9 @@ def table_inherits(cls): class TablespacedTable(ActiveRecord): - __table_name__ = "tablespaced" + @classmethod + def table_name(cls): + return "tablespaced" id: int @@ -156,14 +160,16 @@ def table_tablespace(cls): class TestMySQLTableDeclarationGating: def test_table_declaration_defaults_are_absent(self): class Plain(ActiveRecord): - __table_name__ = "plain_table_defaults" + @classmethod + def table_name(cls): + return "plain_table_defaults" id: int dialect = MySQLDialect() expression = CreateTableStatement( dialect, - Table(dialect, Plain.__table_name__), + Table(dialect, Plain.table_name()), columns=[ColumnDefinition(dialect, "id", IntegerType(dialect))], inherits=Plain.table_inherits(), tablespace=Plain.table_tablespace(), @@ -176,7 +182,7 @@ def test_table_inherits_is_propagated_and_rejected(self): assert dialect.supports_table_inheritance() is False expression = CreateTableStatement( dialect, - Table(dialect, InheritedTable.__table_name__), + Table(dialect, InheritedTable.table_name()), columns=[ColumnDefinition(dialect, "id", IntegerType(dialect))], inherits=InheritedTable.table_inherits(), tablespace=InheritedTable.table_tablespace(), @@ -190,7 +196,7 @@ def test_table_tablespace_is_propagated_and_rejected(self): assert dialect.supports_table_tablespace() is False expression = CreateTableStatement( dialect, - Table(dialect, TablespacedTable.__table_name__), + Table(dialect, TablespacedTable.table_name()), columns=[ColumnDefinition(dialect, "id", IntegerType(dialect))], inherits=TablespacedTable.table_inherits(), tablespace=TablespacedTable.table_tablespace(), diff --git a/tests/rhosocial/activerecord_mysql_test/feature/basic/fields/test_derived_field.py b/tests/rhosocial/activerecord_mysql_test/feature/basic/fields/test_derived_field.py index 85954e83..c5fcaba2 100644 --- a/tests/rhosocial/activerecord_mysql_test/feature/basic/fields/test_derived_field.py +++ b/tests/rhosocial/activerecord_mysql_test/feature/basic/fields/test_derived_field.py @@ -319,7 +319,10 @@ def test_use_column_conflict_raises(self): """UseColumn on derived field must not duplicate a regular field's column name.""" with pytest.raises(TypeError, match="conflicts with a regular field's column name"): class ConflictModel(ActiveRecord): - __table_name__ = "conflict" + @classmethod + def table_name(cls): + return "conflict" + id: Optional[int] = None discount_rate: Annotated[float, UseColumn("disc")] discounted: ClassVar[Annotated[float, DerivedField( @@ -329,7 +332,10 @@ class ConflictModel(ActiveRecord): def test_use_column_no_conflict_different_names(self): """Different column names should not conflict.""" class NoConflict(ActiveRecord): - __table_name__ = "no_conflict" + @classmethod + def table_name(cls): + return "no_conflict" + id: Optional[int] = None discount_rate: Annotated[float, UseColumn("rate")] discounted: ClassVar[Annotated[float, DerivedField( diff --git a/tests/rhosocial/activerecord_mysql_test/feature/basic/fields/test_derived_field_async.py b/tests/rhosocial/activerecord_mysql_test/feature/basic/fields/test_derived_field_async.py index 4934b35f..ecba80a5 100644 --- a/tests/rhosocial/activerecord_mysql_test/feature/basic/fields/test_derived_field_async.py +++ b/tests/rhosocial/activerecord_mysql_test/feature/basic/fields/test_derived_field_async.py @@ -319,7 +319,10 @@ async def test_use_column_conflict_raises(self): """UseColumn on derived field must not duplicate a regular field's column name.""" with pytest.raises(TypeError, match="conflicts with a regular field's column name"): class ConflictModel(ActiveRecord): - __table_name__ = "conflict" + @classmethod + def table_name(cls): + return "conflict" + id: Optional[int] = None discount_rate: Annotated[float, UseColumn("disc")] discounted: ClassVar[Annotated[float, DerivedField( @@ -329,7 +332,10 @@ class ConflictModel(ActiveRecord): async def test_use_column_no_conflict_different_names(self): """Different column names should not conflict.""" class NoConflict(ActiveRecord): - __table_name__ = "no_conflict" + @classmethod + def table_name(cls): + return "no_conflict" + id: Optional[int] = None discount_rate: Annotated[float, UseColumn("rate")] discounted: ClassVar[Annotated[float, DerivedField( diff --git a/tests/rhosocial/activerecord_mysql_test/feature/basic/fixtures/models.py b/tests/rhosocial/activerecord_mysql_test/feature/basic/fixtures/models.py index 9bc6eb95..dc6c9267 100644 --- a/tests/rhosocial/activerecord_mysql_test/feature/basic/fixtures/models.py +++ b/tests/rhosocial/activerecord_mysql_test/feature/basic/fixtures/models.py @@ -31,7 +31,9 @@ class TypeCase(UUIDMixin, ActiveRecord): """A model with a wide variety of data types to test database type handling.""" - __table_name__ = "type_cases" + @classmethod + def table_name(cls): + return "type_cases" username: str email: str @@ -54,7 +56,10 @@ class TypeCase(UUIDMixin, ActiveRecord): class AsyncTypeCase(UUIDMixin, AsyncActiveRecord): """A model with a wide variety of data types to test database type handling.""" - __table_name__ = "type_cases" + @classmethod + def table_name(cls): + return "type_cases" + c: ClassVar[FieldProxy] = FieldProxy() username: str @@ -78,7 +83,9 @@ class AsyncTypeCase(UUIDMixin, AsyncActiveRecord): class TypeTestModel(UUIDMixin, ActiveRecord): """Model class for testing various field types""" - __table_name__ = "type_tests" + @classmethod + def table_name(cls): + return "type_tests" # UUID primary key provided by UUIDMixin string_field: str = Field(default="test string") @@ -92,7 +99,10 @@ class TypeTestModel(UUIDMixin, ActiveRecord): class AsyncTypeTestModel(UUIDMixin, AsyncActiveRecord): """Model class for testing various field types""" - __table_name__ = "type_tests" + @classmethod + def table_name(cls): + return "type_tests" + c: ClassVar[FieldProxy] = FieldProxy() # UUID primary key provided by UUIDMixin @@ -108,7 +118,10 @@ class AsyncTypeTestModel(UUIDMixin, AsyncActiveRecord): class User(IntegerPKMixin, TimestampMixin, ActiveRecord): """A standard User model for general CRUD operation testing.""" - __table_name__ = "users" + @classmethod + def table_name(cls): + return "users" + c: ClassVar[FieldProxy] = FieldProxy() # The IntegerPKMixin is expected to handle the `id` field. @@ -121,7 +134,10 @@ class User(IntegerPKMixin, TimestampMixin, ActiveRecord): class AsyncUser(IntegerPKMixin, TimestampMixin, AsyncActiveRecord): """A standard User model for general CRUD operation testing.""" - __table_name__ = "users" + @classmethod + def table_name(cls): + return "users" + c: ClassVar[FieldProxy] = FieldProxy() # The IntegerPKMixin is expected to handle the `id` field. @@ -137,7 +153,10 @@ class ValidatedFieldUser(IntegerPKMixin, ActiveRecord): A User model with specific, custom field validators to test the framework's validation handling. """ - __table_name__ = "validated_field_users" + @classmethod + def table_name(cls): + return "validated_field_users" + c: ClassVar[FieldProxy] = FieldProxy() id: Optional[int] = None @@ -170,7 +189,10 @@ class AsyncValidatedFieldUser(IntegerPKMixin, AsyncActiveRecord): A User model with specific, custom field validators to test the framework's validation handling. """ - __table_name__ = "validated_field_users" + @classmethod + def table_name(cls): + return "validated_field_users" + c: ClassVar[FieldProxy] = FieldProxy() id: Optional[int] = None @@ -200,7 +222,9 @@ def validate_credit_score(cls, value): class ValidatedUser(IntegerPKMixin, ActiveRecord): """User model for validation testing""" - __table_name__ = "validated_users" + @classmethod + def table_name(cls): + return "validated_users" id: Optional[int] = None username: str = Field(..., min_length=3, max_length=50) @@ -224,7 +248,10 @@ def validate_record(cls, instance: 'ValidatedUser') -> None: class AsyncValidatedUser(IntegerPKMixin, AsyncActiveRecord): """User model for validation testing""" - __table_name__ = "validated_users" + @classmethod + def table_name(cls): + return "validated_users" + c: ClassVar[FieldProxy] = FieldProxy() id: Optional[int] = None @@ -283,14 +310,18 @@ def validate_period(self): class PydanticValidatedModel(PydanticValidatedFieldsMixin, IntegerPKMixin, ActiveRecord): """Model for Pydantic native validation contract tests.""" - __table_name__ = "pydantic_validated_models" + @classmethod + def table_name(cls): + return "pydantic_validated_models" id: Optional[int] = None class AsyncPydanticValidatedModel(PydanticValidatedFieldsMixin, IntegerPKMixin, AsyncActiveRecord): """Async model for Pydantic native validation contract tests.""" - __table_name__ = "pydantic_validated_models" + @classmethod + def table_name(cls): + return "pydantic_validated_models" id: Optional[int] = None @@ -312,7 +343,9 @@ def _do_from_database(self, value: str, target_type: Type, options: Optional[Dic class TypeAdapterTest(ActiveRecord): """Model for testing various type adapter scenarios.""" - __table_name__ = 'type_adapter_tests' + @classmethod + def table_name(cls): + return 'type_adapter_tests' id: Optional[int] = None name: str @@ -329,7 +362,10 @@ class TypeAdapterTest(ActiveRecord): class AsyncTypeAdapterTest(AsyncActiveRecord): """Model for testing various type adapter scenarios.""" - __table_name__ = 'type_adapter_tests' + @classmethod + def table_name(cls): + return 'type_adapter_tests' + c: ClassVar[FieldProxy] = FieldProxy() id: Optional[int] = None @@ -350,7 +386,9 @@ class AsyncTypeAdapterTest(AsyncActiveRecord): class MappedUser(IntegerPKMixin, TimestampMixin, ActiveRecord): """User model with custom column name mappings for testing in basic feature.""" - __table_name__ = "users" + @classmethod + def table_name(cls): + return "users" # Python field: user_id, Database column: id user_id: Annotated[Optional[int], UseColumn("id")] = None @@ -368,7 +406,10 @@ class MappedUser(IntegerPKMixin, TimestampMixin, ActiveRecord): class AsyncMappedUser(IntegerPKMixin, TimestampMixin, AsyncActiveRecord): """User model with custom column name mappings for testing in basic feature.""" - __table_name__ = "users" + @classmethod + def table_name(cls): + return "users" + c: ClassVar[FieldProxy] = FieldProxy() # Python field: user_id, Database column: id @@ -388,7 +429,9 @@ class AsyncMappedUser(IntegerPKMixin, TimestampMixin, AsyncActiveRecord): class MappedPost(IntegerPKMixin, TimestampMixin, ActiveRecord): """Post model with custom column name mappings for testing in basic feature.""" - __table_name__ = "posts" + @classmethod + def table_name(cls): + return "posts" # Python field: post_id, Database column: id post_id: Annotated[Optional[int], UseColumn("id")] = None @@ -411,7 +454,10 @@ class MappedPost(IntegerPKMixin, TimestampMixin, ActiveRecord): class AsyncMappedPost(IntegerPKMixin, TimestampMixin, AsyncActiveRecord): """Post model with custom column name mappings for testing in basic feature.""" - __table_name__ = "posts" + @classmethod + def table_name(cls): + return "posts" + c: ClassVar[FieldProxy] = FieldProxy() # Python field: post_id, Database column: id @@ -436,7 +482,9 @@ class AsyncMappedPost(IntegerPKMixin, TimestampMixin, AsyncActiveRecord): class MappedComment(IntegerPKMixin, TimestampMixin, ActiveRecord): """Comment model with custom column name mappings for testing in basic feature.""" - __table_name__ = "comments" + @classmethod + def table_name(cls): + return "comments" # Python field: comment_id, Database column: id comment_id: Annotated[Optional[int], UseColumn("id")] = None @@ -460,7 +508,10 @@ class MappedComment(IntegerPKMixin, TimestampMixin, ActiveRecord): class AsyncMappedComment(IntegerPKMixin, TimestampMixin, AsyncActiveRecord): """Comment model with custom column name mappings for testing in basic feature.""" - __table_name__ = "comments" + @classmethod + def table_name(cls): + return "comments" + c: ClassVar[FieldProxy] = FieldProxy() # Python field: comment_id, Database column: id @@ -504,7 +555,9 @@ class ColumnMappingModel(ActiveRecord): A model demonstrating various valid uses of UseColumn and UseAdapter, including mapping the primary key attribute. """ - __table_name__ = 'column_mapping_items' + @classmethod + def table_name(cls): + return 'column_mapping_items' # Primary key defaults to 'id'. item_id attribute maps to this 'id' column. item_id: Annotated[Optional[int], UseColumn("id")] = Field(default=None) @@ -517,7 +570,10 @@ class AsyncColumnMappingModel(AsyncActiveRecord): A model demonstrating various valid uses of UseColumn and UseAdapter, including mapping the primary key attribute. """ - __table_name__ = 'column_mapping_items' + @classmethod + def table_name(cls): + return 'column_mapping_items' + c: ClassVar[FieldProxy] = FieldProxy() # Primary key defaults to 'id'. item_id attribute maps to this 'id' column. @@ -603,7 +659,9 @@ def _do_from_database(self, value: str, target_type: Type, options: Optional[Dic class MixedAnnotationModel(ActiveRecord): """A model with various combinations of annotations to test field mapping and adapters.""" - __table_name__ = "mixed_annotation_items" + @classmethod + def table_name(cls): + return "mixed_annotation_items" # 1. Standard Python type name: str @@ -626,7 +684,10 @@ class MixedAnnotationModel(ActiveRecord): class AsyncMixedAnnotationModel(AsyncActiveRecord): """A model with various combinations of annotations to test field mapping and adapters.""" - __table_name__ = "mixed_annotation_items" + @classmethod + def table_name(cls): + return "mixed_annotation_items" + c: ClassVar[FieldProxy] = FieldProxy() # 1. Standard Python type @@ -650,7 +711,10 @@ class AsyncMixedAnnotationModel(AsyncActiveRecord): class BulkUser(IntegerPKMixin, ActiveRecord): - __table_name__ = "bulk_users" + @classmethod + def table_name(cls): + return "bulk_users" + c: ClassVar[FieldProxy] = FieldProxy() id: Optional[int] = None @@ -660,7 +724,10 @@ class BulkUser(IntegerPKMixin, ActiveRecord): class AsyncBulkUser(IntegerPKMixin, AsyncActiveRecord): - __table_name__ = "bulk_users" + @classmethod + def table_name(cls): + return "bulk_users" + c: ClassVar[FieldProxy] = FieldProxy() id: Optional[int] = None @@ -675,8 +742,14 @@ class AsyncBulkUser(IntegerPKMixin, AsyncActiveRecord): class OrderItem(CompositePKMixin, ActiveRecord): """Composite PK (order_id, product_id), PK provided by application.""" - __table_name__ = "order_items" - __primary_key__ = ("order_id", "product_id") + @classmethod + def table_name(cls): + return "order_items" + + @classmethod + def primary_key(cls): + return ("order_id", "product_id") + c: ClassVar[FieldProxy] = FieldProxy() order_id: int @@ -687,8 +760,14 @@ class OrderItem(CompositePKMixin, ActiveRecord): class AsyncOrderItem(CompositePKMixin, AsyncActiveRecord): """Async variant of OrderItem.""" - __table_name__ = "order_items" - __primary_key__ = ("order_id", "product_id") + @classmethod + def table_name(cls): + return "order_items" + + @classmethod + def primary_key(cls): + return ("order_id", "product_id") + c: ClassVar[FieldProxy] = FieldProxy() order_id: int @@ -699,8 +778,14 @@ class AsyncOrderItem(CompositePKMixin, AsyncActiveRecord): class StoreInventory(CompositePKMixin, ActiveRecord): """Triple-column composite PK.""" - __table_name__ = "store_inventory" - __primary_key__ = ("store_id", "product_id", "batch_id") + @classmethod + def table_name(cls): + return "store_inventory" + + @classmethod + def primary_key(cls): + return ("store_id", "product_id", "batch_id") + c: ClassVar[FieldProxy] = FieldProxy() store_id: int @@ -711,8 +796,14 @@ class StoreInventory(CompositePKMixin, ActiveRecord): class AsyncStoreInventory(CompositePKMixin, AsyncActiveRecord): """Async variant of StoreInventory.""" - __table_name__ = "store_inventory" - __primary_key__ = ("store_id", "product_id", "batch_id") + @classmethod + def table_name(cls): + return "store_inventory" + + @classmethod + def primary_key(cls): + return ("store_id", "product_id", "batch_id") + c: ClassVar[FieldProxy] = FieldProxy() store_id: int @@ -723,7 +814,10 @@ class AsyncStoreInventory(CompositePKMixin, AsyncActiveRecord): class Order(IntegerPKMixin, TimestampMixin, ActiveRecord): """Single-column auto-increment PK — backward compatibility control group.""" - __table_name__ = "orders" + @classmethod + def table_name(cls): + return "orders" + c: ClassVar[FieldProxy] = FieldProxy() id: Optional[int] = None @@ -732,7 +826,10 @@ class Order(IntegerPKMixin, TimestampMixin, ActiveRecord): class AsyncOrder(IntegerPKMixin, TimestampMixin, AsyncActiveRecord): """Async variant of Order.""" - __table_name__ = "orders" + @classmethod + def table_name(cls): + return "orders" + c: ClassVar[FieldProxy] = FieldProxy() id: Optional[int] = None @@ -741,8 +838,13 @@ class AsyncOrder(IntegerPKMixin, TimestampMixin, AsyncActiveRecord): class MappedOrderItem(CompositePKMixin, ActiveRecord): """Composite PK with UseColumn mapping — Python field names differ from DB column names.""" - __table_name__ = "order_items" - __primary_key__ = ("order_id", "product_id") + @classmethod + def table_name(cls): + return "order_items" + + @classmethod + def primary_key(cls): + return ("order_id", "product_id") order_ref: Annotated[int, UseColumn("order_id")] product_ref: Annotated[int, UseColumn("product_id")] @@ -752,8 +854,14 @@ class MappedOrderItem(CompositePKMixin, ActiveRecord): class AsyncMappedOrderItem(CompositePKMixin, AsyncActiveRecord): """Async variant of MappedOrderItem.""" - __table_name__ = "order_items" - __primary_key__ = ("order_id", "product_id") + @classmethod + def table_name(cls): + return "order_items" + + @classmethod + def primary_key(cls): + return ("order_id", "product_id") + c: ClassVar[FieldProxy] = FieldProxy() order_ref: Annotated[int, UseColumn("order_id")] @@ -771,7 +879,9 @@ class AsyncMappedOrderItem(CompositePKMixin, AsyncActiveRecord): class Product(ActiveRecord): - __table_name__ = "product" + @classmethod + def table_name(cls): + return "product" id: Optional[int] = None name: str @@ -788,7 +898,9 @@ class Product(ActiveRecord): class AsyncProduct(AsyncActiveRecord): - __table_name__ = "product" + @classmethod + def table_name(cls): + return "product" id: Optional[int] = None name: str @@ -806,7 +918,9 @@ class AsyncProduct(AsyncActiveRecord): class ProductFormA(ActiveRecord): """Form A declaration: ClassVar[DerivedField] = DerivedField(...).""" - __table_name__ = "product" + @classmethod + def table_name(cls): + return "product" id: Optional[int] = None name: str @@ -823,7 +937,9 @@ class ProductFormA(ActiveRecord): class AsyncProductFormA(AsyncActiveRecord): - __table_name__ = "product" + @classmethod + def table_name(cls): + return "product" id: Optional[int] = None name: str @@ -855,7 +971,9 @@ def supported_types(self) -> Dict[Type, Set[Type]]: class ProductWithProxy(ActiveRecord): """Product model using FieldProxy in DerivedField expressions.""" - __table_name__ = "product" + @classmethod + def table_name(cls): + return "product" c: ClassVar[FieldProxy] = FieldProxy() id: Optional[int] = None @@ -873,7 +991,9 @@ class ProductWithProxy(ActiveRecord): class AsyncProductWithProxy(AsyncActiveRecord): - __table_name__ = "product" + @classmethod + def table_name(cls): + return "product" c: ClassVar[FieldProxy] = FieldProxy() id: Optional[int] = None @@ -892,7 +1012,9 @@ class AsyncProductWithProxy(AsyncActiveRecord): class ProductWithColumnAndAdapter(ActiveRecord): """Product model with UseColumn and UseAdapter on derived fields.""" - __table_name__ = "product" + @classmethod + def table_name(cls): + return "product" id: Optional[int] = None name: str @@ -909,7 +1031,9 @@ class ProductWithColumnAndAdapter(ActiveRecord): class AsyncProductWithColumnAndAdapter(AsyncActiveRecord): - __table_name__ = "product" + @classmethod + def table_name(cls): + return "product" id: Optional[int] = None name: str diff --git a/tests/rhosocial/activerecord_mysql_test/feature/basic/fixtures/models_py310.py b/tests/rhosocial/activerecord_mysql_test/feature/basic/fixtures/models_py310.py index 3a7b6049..6768e14d 100644 --- a/tests/rhosocial/activerecord_mysql_test/feature/basic/fixtures/models_py310.py +++ b/tests/rhosocial/activerecord_mysql_test/feature/basic/fixtures/models_py310.py @@ -11,7 +11,7 @@ import re from datetime import date, time, datetime from decimal import Decimal -from typing import Optional, Type, Literal, Union, Any, Dict, List, Set +from typing import Optional, Type, Literal, Any, Dict, List import json from pydantic import EmailStr, Field, field_validator, model_validator @@ -34,7 +34,9 @@ class TypeCase(UUIDMixin, ActiveRecord): Python 3.10+ version using | syntax instead of Optional. """ - __table_name__ = "type_cases" + @classmethod + def table_name(cls): + return "type_cases" username: str email: str @@ -61,7 +63,10 @@ class AsyncTypeCase(UUIDMixin, AsyncActiveRecord): Python 3.10+ version using | syntax instead of Optional. """ - __table_name__ = "type_cases" + @classmethod + def table_name(cls): + return "type_cases" + c: ClassVar[FieldProxy] = FieldProxy() username: str @@ -89,7 +94,9 @@ class TypeTestModel(UUIDMixin, ActiveRecord): Python 3.10+ version using | syntax instead of Optional. """ - __table_name__ = "type_tests" + @classmethod + def table_name(cls): + return "type_tests" # UUID primary key provided by UUIDMixin string_field: str = Field(default="test string") @@ -107,7 +114,10 @@ class AsyncTypeTestModel(UUIDMixin, AsyncActiveRecord): Python 3.10+ version using | syntax instead of Optional. """ - __table_name__ = "type_tests" + @classmethod + def table_name(cls): + return "type_tests" + c: ClassVar[FieldProxy] = FieldProxy() # UUID primary key provided by UUIDMixin @@ -126,7 +136,10 @@ class User(IntegerPKMixin, TimestampMixin, ActiveRecord): Python 3.10+ version using | syntax instead of Optional. """ - __table_name__ = "users" + @classmethod + def table_name(cls): + return "users" + c: ClassVar[FieldProxy] = FieldProxy() # The IntegerPKMixin is expected to handle the `id` field. @@ -143,7 +156,10 @@ class AsyncUser(IntegerPKMixin, TimestampMixin, AsyncActiveRecord): Python 3.10+ version using | syntax instead of Optional. """ - __table_name__ = "users" + @classmethod + def table_name(cls): + return "users" + c: ClassVar[FieldProxy] = FieldProxy() # The IntegerPKMixin is expected to handle the `id` field. @@ -161,7 +177,10 @@ class ValidatedFieldUser(IntegerPKMixin, ActiveRecord): Python 3.10+ version using | syntax instead of Optional. """ - __table_name__ = "validated_field_users" + @classmethod + def table_name(cls): + return "validated_field_users" + c: ClassVar[FieldProxy] = FieldProxy() id: int | None = None @@ -194,7 +213,10 @@ class AsyncValidatedFieldUser(IntegerPKMixin, AsyncActiveRecord): Python 3.10+ version using | syntax instead of Optional. """ - __table_name__ = "validated_field_users" + @classmethod + def table_name(cls): + return "validated_field_users" + c: ClassVar[FieldProxy] = FieldProxy() id: int | None = None @@ -226,7 +248,9 @@ class ValidatedUser(IntegerPKMixin, ActiveRecord): Python 3.10+ version using | syntax instead of Optional. """ - __table_name__ = "validated_users" + @classmethod + def table_name(cls): + return "validated_users" id: int | None = None username: str = Field(..., min_length=3, max_length=50) @@ -253,7 +277,10 @@ class AsyncValidatedUser(IntegerPKMixin, AsyncActiveRecord): Python 3.10+ version using | syntax instead of Optional. """ - __table_name__ = "validated_users" + @classmethod + def table_name(cls): + return "validated_users" + c: ClassVar[FieldProxy] = FieldProxy() id: int | None = None @@ -311,14 +338,18 @@ def validate_period(self): class PydanticValidatedModel(PydanticValidatedFieldsMixin, IntegerPKMixin, ActiveRecord): """Model for Pydantic native validation contract tests.""" - __table_name__ = "pydantic_validated_models" + @classmethod + def table_name(cls): + return "pydantic_validated_models" id: int | None = None class AsyncPydanticValidatedModel(PydanticValidatedFieldsMixin, IntegerPKMixin, AsyncActiveRecord): """Async model for Pydantic native validation contract tests.""" - __table_name__ = "pydantic_validated_models" + @classmethod + def table_name(cls): + return "pydantic_validated_models" id: int | None = None @@ -337,7 +368,9 @@ class TypeAdapterTest(ActiveRecord): Python 3.10+ version using | syntax instead of Optional and Union. """ - __table_name__ = 'type_adapter_tests' + @classmethod + def table_name(cls): + return 'type_adapter_tests' id: int | None = None name: str @@ -358,7 +391,10 @@ class AsyncTypeAdapterTest(AsyncActiveRecord): Python 3.10+ version using | syntax instead of Optional and Union. """ - __table_name__ = 'type_adapter_tests' + @classmethod + def table_name(cls): + return 'type_adapter_tests' + c: ClassVar[FieldProxy] = FieldProxy() id: int | None = None @@ -380,7 +416,9 @@ class MappedUser(IntegerPKMixin, TimestampMixin, ActiveRecord): Python 3.10+ version using | syntax instead of Optional. """ - __table_name__ = "users" + @classmethod + def table_name(cls): + return "users" # Python field: user_id, Database column: id user_id: Annotated[int | None, UseColumn("id")] = None @@ -400,7 +438,10 @@ class AsyncMappedUser(IntegerPKMixin, TimestampMixin, AsyncActiveRecord): Python 3.10+ version using | syntax instead of Optional. """ - __table_name__ = "users" + @classmethod + def table_name(cls): + return "users" + c: ClassVar[FieldProxy] = FieldProxy() # Python field: user_id, Database column: id @@ -421,7 +462,9 @@ class MappedPost(IntegerPKMixin, TimestampMixin, ActiveRecord): Python 3.10+ version using | syntax instead of Optional. """ - __table_name__ = "posts" + @classmethod + def table_name(cls): + return "posts" # Python field: post_id, Database column: id post_id: Annotated[int | None, UseColumn("id")] = None @@ -447,7 +490,10 @@ class AsyncMappedPost(IntegerPKMixin, TimestampMixin, AsyncActiveRecord): Python 3.10+ version using | syntax instead of Optional. """ - __table_name__ = "posts" + @classmethod + def table_name(cls): + return "posts" + c: ClassVar[FieldProxy] = FieldProxy() # Python field: post_id, Database column: id @@ -474,7 +520,9 @@ class MappedComment(IntegerPKMixin, TimestampMixin, ActiveRecord): Python 3.10+ version using | syntax instead of Optional. """ - __table_name__ = "comments" + @classmethod + def table_name(cls): + return "comments" # Python field: comment_id, Database column: id comment_id: Annotated[int | None, UseColumn("id")] = None @@ -500,7 +548,10 @@ class AsyncMappedComment(IntegerPKMixin, TimestampMixin, AsyncActiveRecord): Python 3.10+ version using | syntax instead of Optional. """ - __table_name__ = "comments" + @classmethod + def table_name(cls): + return "comments" + c: ClassVar[FieldProxy] = FieldProxy() # Python field: comment_id, Database column: id @@ -542,7 +593,9 @@ class ColumnMappingModel(ActiveRecord): Python 3.10+ version using | syntax instead of Optional. """ - __table_name__ = 'column_mapping_items' + @classmethod + def table_name(cls): + return 'column_mapping_items' # Primary key defaults to 'id'. item_id attribute maps to this 'id' column. item_id: Annotated[int | None, UseColumn("id")] = Field(default=None) @@ -557,7 +610,10 @@ class AsyncColumnMappingModel(AsyncActiveRecord): Python 3.10+ version using | syntax instead of Optional. """ - __table_name__ = 'column_mapping_items' + @classmethod + def table_name(cls): + return 'column_mapping_items' + c: ClassVar[FieldProxy] = FieldProxy() # Primary key defaults to 'id'. item_id attribute maps to this 'id' column. @@ -636,7 +692,9 @@ class MixedAnnotationModel(ActiveRecord): Python 3.10+ version using | syntax instead of Optional. """ - __table_name__ = "mixed_annotation_items" + @classmethod + def table_name(cls): + return "mixed_annotation_items" # 1. Standard Python type name: str @@ -662,7 +720,10 @@ class AsyncMixedAnnotationModel(AsyncActiveRecord): Python 3.10+ version using | syntax instead of Optional. """ - __table_name__ = "mixed_annotation_items" + @classmethod + def table_name(cls): + return "mixed_annotation_items" + c: ClassVar[FieldProxy] = FieldProxy() # 1. Standard Python type @@ -689,8 +750,14 @@ class AsyncMixedAnnotationModel(AsyncActiveRecord): class OrderItem(CompositePKMixin, ActiveRecord): """Composite PK (order_id, product_id), PK provided by application.""" - __table_name__ = "order_items" - __primary_key__ = ("order_id", "product_id") + @classmethod + def table_name(cls): + return "order_items" + + @classmethod + def primary_key(cls): + return ("order_id", "product_id") + c: ClassVar[FieldProxy] = FieldProxy() order_id: int @@ -701,8 +768,14 @@ class OrderItem(CompositePKMixin, ActiveRecord): class AsyncOrderItem(CompositePKMixin, AsyncActiveRecord): """Async variant of OrderItem.""" - __table_name__ = "order_items" - __primary_key__ = ("order_id", "product_id") + @classmethod + def table_name(cls): + return "order_items" + + @classmethod + def primary_key(cls): + return ("order_id", "product_id") + c: ClassVar[FieldProxy] = FieldProxy() order_id: int @@ -713,8 +786,14 @@ class AsyncOrderItem(CompositePKMixin, AsyncActiveRecord): class StoreInventory(CompositePKMixin, ActiveRecord): """Triple-column composite PK.""" - __table_name__ = "store_inventory" - __primary_key__ = ("store_id", "product_id", "batch_id") + @classmethod + def table_name(cls): + return "store_inventory" + + @classmethod + def primary_key(cls): + return ("store_id", "product_id", "batch_id") + c: ClassVar[FieldProxy] = FieldProxy() store_id: int @@ -725,8 +804,14 @@ class StoreInventory(CompositePKMixin, ActiveRecord): class AsyncStoreInventory(CompositePKMixin, AsyncActiveRecord): """Async variant of StoreInventory.""" - __table_name__ = "store_inventory" - __primary_key__ = ("store_id", "product_id", "batch_id") + @classmethod + def table_name(cls): + return "store_inventory" + + @classmethod + def primary_key(cls): + return ("store_id", "product_id", "batch_id") + c: ClassVar[FieldProxy] = FieldProxy() store_id: int @@ -737,7 +822,10 @@ class AsyncStoreInventory(CompositePKMixin, AsyncActiveRecord): class Order(IntegerPKMixin, TimestampMixin, ActiveRecord): """Single-column auto-increment PK -- backward compatibility control group.""" - __table_name__ = "orders" + @classmethod + def table_name(cls): + return "orders" + c: ClassVar[FieldProxy] = FieldProxy() id: Optional[int] = None @@ -746,7 +834,10 @@ class Order(IntegerPKMixin, TimestampMixin, ActiveRecord): class AsyncOrder(IntegerPKMixin, TimestampMixin, AsyncActiveRecord): """Async variant of Order.""" - __table_name__ = "orders" + @classmethod + def table_name(cls): + return "orders" + c: ClassVar[FieldProxy] = FieldProxy() id: Optional[int] = None @@ -755,8 +846,13 @@ class AsyncOrder(IntegerPKMixin, TimestampMixin, AsyncActiveRecord): class MappedOrderItem(CompositePKMixin, ActiveRecord): """Composite PK with UseColumn mapping -- Python field names differ from DB column names.""" - __table_name__ = "order_items" - __primary_key__ = ("order_id", "product_id") + @classmethod + def table_name(cls): + return "order_items" + + @classmethod + def primary_key(cls): + return ("order_id", "product_id") order_ref: Annotated[int, UseColumn("order_id")] product_ref: Annotated[int, UseColumn("product_id")] @@ -766,8 +862,14 @@ class MappedOrderItem(CompositePKMixin, ActiveRecord): class AsyncMappedOrderItem(CompositePKMixin, AsyncActiveRecord): """Async variant of MappedOrderItem.""" - __table_name__ = "order_items" - __primary_key__ = ("order_id", "product_id") + @classmethod + def table_name(cls): + return "order_items" + + @classmethod + def primary_key(cls): + return ("order_id", "product_id") + c: ClassVar[FieldProxy] = FieldProxy() order_ref: Annotated[int, UseColumn("order_id")] @@ -777,7 +879,10 @@ class AsyncMappedOrderItem(CompositePKMixin, AsyncActiveRecord): class BulkUser(IntegerPKMixin, ActiveRecord): - __table_name__ = "bulk_users" + @classmethod + def table_name(cls): + return "bulk_users" + c: ClassVar[FieldProxy] = FieldProxy() id: int | None = None @@ -787,7 +892,10 @@ class BulkUser(IntegerPKMixin, ActiveRecord): class AsyncBulkUser(IntegerPKMixin, AsyncActiveRecord): - __table_name__ = "bulk_users" + @classmethod + def table_name(cls): + return "bulk_users" + c: ClassVar[FieldProxy] = FieldProxy() id: int | None = None diff --git a/tests/rhosocial/activerecord_mysql_test/feature/basic/fixtures/models_py311.py b/tests/rhosocial/activerecord_mysql_test/feature/basic/fixtures/models_py311.py index 5a6f6004..a2c1e092 100644 --- a/tests/rhosocial/activerecord_mysql_test/feature/basic/fixtures/models_py311.py +++ b/tests/rhosocial/activerecord_mysql_test/feature/basic/fixtures/models_py311.py @@ -15,7 +15,7 @@ import re from datetime import date, time, datetime from decimal import Decimal -from typing import Optional, Type, Literal, Union, Any, Dict, List, Self, Set +from typing import Optional, Type, Literal, Any, Dict, List, Self import json from pydantic import EmailStr, Field, field_validator, model_validator @@ -38,7 +38,9 @@ class TypeCase(UUIDMixin, ActiveRecord): Python 3.11+ version using | syntax and Self type. """ - __table_name__ = "type_cases" + @classmethod + def table_name(cls): + return "type_cases" username: str email: str @@ -72,7 +74,10 @@ class AsyncTypeCase(UUIDMixin, AsyncActiveRecord): Python 3.11+ version using | syntax and Self type. """ - __table_name__ = "type_cases" + @classmethod + def table_name(cls): + return "type_cases" + c: ClassVar[FieldProxy] = FieldProxy() username: str @@ -107,7 +112,9 @@ class TypeTestModel(UUIDMixin, ActiveRecord): Python 3.11+ version using | syntax and Self type. """ - __table_name__ = "type_tests" + @classmethod + def table_name(cls): + return "type_tests" # UUID primary key provided by UUIDMixin string_field: str = Field(default="test string") @@ -125,7 +132,10 @@ class AsyncTypeTestModel(UUIDMixin, AsyncActiveRecord): Python 3.11+ version using | syntax and Self type. """ - __table_name__ = "type_tests" + @classmethod + def table_name(cls): + return "type_tests" + c: ClassVar[FieldProxy] = FieldProxy() # UUID primary key provided by UUIDMixin @@ -144,7 +154,10 @@ class User(IntegerPKMixin, TimestampMixin, ActiveRecord): Python 3.11+ version using | syntax and Self type. """ - __table_name__ = "users" + @classmethod + def table_name(cls): + return "users" + c: ClassVar[FieldProxy] = FieldProxy() id: int | None = None @@ -185,7 +198,10 @@ class AsyncUser(IntegerPKMixin, TimestampMixin, AsyncActiveRecord): Python 3.11+ version using | syntax and Self type. """ - __table_name__ = "users" + @classmethod + def table_name(cls): + return "users" + c: ClassVar[FieldProxy] = FieldProxy() id: int | None = None @@ -208,7 +224,10 @@ class ValidatedFieldUser(IntegerPKMixin, ActiveRecord): Python 3.11+ version using | syntax and Self type. """ - __table_name__ = "validated_field_users" + @classmethod + def table_name(cls): + return "validated_field_users" + c: ClassVar[FieldProxy] = FieldProxy() id: int | None = None @@ -241,7 +260,10 @@ class AsyncValidatedFieldUser(IntegerPKMixin, AsyncActiveRecord): Python 3.11+ version using | syntax and Self type. """ - __table_name__ = "validated_field_users" + @classmethod + def table_name(cls): + return "validated_field_users" + c: ClassVar[FieldProxy] = FieldProxy() id: int | None = None @@ -273,7 +295,9 @@ class ValidatedUser(IntegerPKMixin, ActiveRecord): Python 3.11+ version using | syntax and Self type. """ - __table_name__ = "validated_users" + @classmethod + def table_name(cls): + return "validated_users" id: int | None = None username: str = Field(..., min_length=3, max_length=50) @@ -300,7 +324,10 @@ class AsyncValidatedUser(IntegerPKMixin, AsyncActiveRecord): Python 3.11+ version using | syntax and Self type. """ - __table_name__ = "validated_users" + @classmethod + def table_name(cls): + return "validated_users" + c: ClassVar[FieldProxy] = FieldProxy() id: int | None = None @@ -358,14 +385,18 @@ def validate_period(self): class PydanticValidatedModel(PydanticValidatedFieldsMixin, IntegerPKMixin, ActiveRecord): """Model for Pydantic native validation contract tests.""" - __table_name__ = "pydantic_validated_models" + @classmethod + def table_name(cls): + return "pydantic_validated_models" id: int | None = None class AsyncPydanticValidatedModel(PydanticValidatedFieldsMixin, IntegerPKMixin, AsyncActiveRecord): """Async model for Pydantic native validation contract tests.""" - __table_name__ = "pydantic_validated_models" + @classmethod + def table_name(cls): + return "pydantic_validated_models" id: int | None = None @@ -384,7 +415,9 @@ class TypeAdapterTest(ActiveRecord): Python 3.11+ version using | syntax. """ - __table_name__ = 'type_adapter_tests' + @classmethod + def table_name(cls): + return 'type_adapter_tests' id: int | None = None name: str @@ -402,7 +435,10 @@ class AsyncTypeAdapterTest(AsyncActiveRecord): Python 3.11+ version using | syntax. """ - __table_name__ = 'type_adapter_tests' + @classmethod + def table_name(cls): + return 'type_adapter_tests' + c: ClassVar[FieldProxy] = FieldProxy() id: int | None = None @@ -421,7 +457,9 @@ class MappedUser(IntegerPKMixin, TimestampMixin, ActiveRecord): Python 3.11+ version using | syntax and Self type. """ - __table_name__ = "users" + @classmethod + def table_name(cls): + return "users" user_id: Annotated[int | None, UseColumn("id")] = None user_name: Annotated[str, UseColumn("username")] @@ -439,7 +477,10 @@ class AsyncMappedUser(IntegerPKMixin, TimestampMixin, AsyncActiveRecord): Python 3.11+ version using | syntax. """ - __table_name__ = "users" + @classmethod + def table_name(cls): + return "users" + c: ClassVar[FieldProxy] = FieldProxy() user_id: Annotated[int | None, UseColumn("id")] = None @@ -453,7 +494,9 @@ class MappedPost(IntegerPKMixin, TimestampMixin, ActiveRecord): Python 3.11+ version using | syntax. """ - __table_name__ = "posts" + @classmethod + def table_name(cls): + return "posts" post_id: Annotated[int | None, UseColumn("id")] = None author_id: Annotated[int, UseColumn("author")] @@ -468,7 +511,10 @@ class AsyncMappedPost(IntegerPKMixin, TimestampMixin, AsyncActiveRecord): Python 3.11+ version using | syntax. """ - __table_name__ = "posts" + @classmethod + def table_name(cls): + return "posts" + c: ClassVar[FieldProxy] = FieldProxy() post_id: Annotated[int | None, UseColumn("id")] = None @@ -484,7 +530,9 @@ class MappedComment(IntegerPKMixin, TimestampMixin, ActiveRecord): Python 3.11+ version using | syntax. """ - __table_name__ = "comments" + @classmethod + def table_name(cls): + return "comments" comment_id: Annotated[int | None, UseColumn("id")] = None post_id: Annotated[int, UseColumn("post_ref")] @@ -499,7 +547,10 @@ class AsyncMappedComment(IntegerPKMixin, TimestampMixin, AsyncActiveRecord): Python 3.11+ version using | syntax. """ - __table_name__ = "comments" + @classmethod + def table_name(cls): + return "comments" + c: ClassVar[FieldProxy] = FieldProxy() comment_id: Annotated[int | None, UseColumn("id")] = None @@ -529,7 +580,9 @@ class ColumnMappingModel(ActiveRecord): Python 3.11+ version using | syntax. """ - __table_name__ = 'column_mapping_items' + @classmethod + def table_name(cls): + return 'column_mapping_items' item_id: Annotated[int | None, UseColumn("id")] = Field(default=None) name: str @@ -542,7 +595,10 @@ class AsyncColumnMappingModel(AsyncActiveRecord): Python 3.11+ version using | syntax. """ - __table_name__ = 'column_mapping_items' + @classmethod + def table_name(cls): + return 'column_mapping_items' + c: ClassVar[FieldProxy] = FieldProxy() item_id: Annotated[int | None, UseColumn("id")] = Field(default=None) @@ -620,7 +676,9 @@ class MixedAnnotationModel(ActiveRecord): Python 3.11+ version using | syntax. """ - __table_name__ = "mixed_annotation_items" + @classmethod + def table_name(cls): + return "mixed_annotation_items" name: str item_id: Annotated[int, UseColumn("id")] @@ -644,7 +702,10 @@ class AsyncMixedAnnotationModel(AsyncActiveRecord): Python 3.11+ version using | syntax. """ - __table_name__ = "mixed_annotation_items" + @classmethod + def table_name(cls): + return "mixed_annotation_items" + c: ClassVar[FieldProxy] = FieldProxy() name: str @@ -660,8 +721,14 @@ class AsyncMixedAnnotationModel(AsyncActiveRecord): class OrderItem(CompositePKMixin, ActiveRecord): """Composite PK (order_id, product_id), PK provided by application.""" - __table_name__ = "order_items" - __primary_key__ = ("order_id", "product_id") + @classmethod + def table_name(cls): + return "order_items" + + @classmethod + def primary_key(cls): + return ("order_id", "product_id") + c: ClassVar[FieldProxy] = FieldProxy() order_id: int @@ -672,8 +739,14 @@ class OrderItem(CompositePKMixin, ActiveRecord): class AsyncOrderItem(CompositePKMixin, AsyncActiveRecord): """Async variant of OrderItem.""" - __table_name__ = "order_items" - __primary_key__ = ("order_id", "product_id") + @classmethod + def table_name(cls): + return "order_items" + + @classmethod + def primary_key(cls): + return ("order_id", "product_id") + c: ClassVar[FieldProxy] = FieldProxy() order_id: int @@ -684,8 +757,14 @@ class AsyncOrderItem(CompositePKMixin, AsyncActiveRecord): class StoreInventory(CompositePKMixin, ActiveRecord): """Triple-column composite PK.""" - __table_name__ = "store_inventory" - __primary_key__ = ("store_id", "product_id", "batch_id") + @classmethod + def table_name(cls): + return "store_inventory" + + @classmethod + def primary_key(cls): + return ("store_id", "product_id", "batch_id") + c: ClassVar[FieldProxy] = FieldProxy() store_id: int @@ -696,8 +775,14 @@ class StoreInventory(CompositePKMixin, ActiveRecord): class AsyncStoreInventory(CompositePKMixin, AsyncActiveRecord): """Async variant of StoreInventory.""" - __table_name__ = "store_inventory" - __primary_key__ = ("store_id", "product_id", "batch_id") + @classmethod + def table_name(cls): + return "store_inventory" + + @classmethod + def primary_key(cls): + return ("store_id", "product_id", "batch_id") + c: ClassVar[FieldProxy] = FieldProxy() store_id: int @@ -708,7 +793,10 @@ class AsyncStoreInventory(CompositePKMixin, AsyncActiveRecord): class Order(IntegerPKMixin, TimestampMixin, ActiveRecord): """Single-column auto-increment PK -- backward compatibility control group.""" - __table_name__ = "orders" + @classmethod + def table_name(cls): + return "orders" + c: ClassVar[FieldProxy] = FieldProxy() id: Optional[int] = None @@ -717,7 +805,10 @@ class Order(IntegerPKMixin, TimestampMixin, ActiveRecord): class AsyncOrder(IntegerPKMixin, TimestampMixin, AsyncActiveRecord): """Async variant of Order.""" - __table_name__ = "orders" + @classmethod + def table_name(cls): + return "orders" + c: ClassVar[FieldProxy] = FieldProxy() id: Optional[int] = None @@ -726,8 +817,13 @@ class AsyncOrder(IntegerPKMixin, TimestampMixin, AsyncActiveRecord): class MappedOrderItem(CompositePKMixin, ActiveRecord): """Composite PK with UseColumn mapping -- Python field names differ from DB column names.""" - __table_name__ = "order_items" - __primary_key__ = ("order_id", "product_id") + @classmethod + def table_name(cls): + return "order_items" + + @classmethod + def primary_key(cls): + return ("order_id", "product_id") order_ref: Annotated[int, UseColumn("order_id")] product_ref: Annotated[int, UseColumn("product_id")] @@ -737,8 +833,14 @@ class MappedOrderItem(CompositePKMixin, ActiveRecord): class AsyncMappedOrderItem(CompositePKMixin, AsyncActiveRecord): """Async variant of MappedOrderItem.""" - __table_name__ = "order_items" - __primary_key__ = ("order_id", "product_id") + @classmethod + def table_name(cls): + return "order_items" + + @classmethod + def primary_key(cls): + return ("order_id", "product_id") + c: ClassVar[FieldProxy] = FieldProxy() order_ref: Annotated[int, UseColumn("order_id")] @@ -748,7 +850,10 @@ class AsyncMappedOrderItem(CompositePKMixin, AsyncActiveRecord): class BulkUser(IntegerPKMixin, ActiveRecord): - __table_name__ = "bulk_users" + @classmethod + def table_name(cls): + return "bulk_users" + c: ClassVar[FieldProxy] = FieldProxy() id: int | None = None @@ -758,7 +863,10 @@ class BulkUser(IntegerPKMixin, ActiveRecord): class AsyncBulkUser(IntegerPKMixin, AsyncActiveRecord): - __table_name__ = "bulk_users" + @classmethod + def table_name(cls): + return "bulk_users" + c: ClassVar[FieldProxy] = FieldProxy() id: int | None = None diff --git a/tests/rhosocial/activerecord_mysql_test/feature/basic/fixtures/models_py312.py b/tests/rhosocial/activerecord_mysql_test/feature/basic/fixtures/models_py312.py index f0f74f59..ec71b7e1 100644 --- a/tests/rhosocial/activerecord_mysql_test/feature/basic/fixtures/models_py312.py +++ b/tests/rhosocial/activerecord_mysql_test/feature/basic/fixtures/models_py312.py @@ -15,7 +15,7 @@ import re from datetime import date, time, datetime from decimal import Decimal -from typing import Optional, Type, Literal, Union, Any, Dict, List, Self, Set, override +from typing import Optional, Type, Literal, Any, Dict, List, Self, override import json from pydantic import EmailStr, Field, field_validator, model_validator @@ -38,7 +38,9 @@ class TypeCase(UUIDMixin, ActiveRecord): Python 3.12+ version using | syntax, Self type, and @override. """ - __table_name__ = "type_cases" + @classmethod + def table_name(cls): + return "type_cases" username: str email: str @@ -69,7 +71,10 @@ class AsyncTypeCase(UUIDMixin, AsyncActiveRecord): Python 3.12+ version using | syntax, Self type, and @override. """ - __table_name__ = "type_cases" + @classmethod + def table_name(cls): + return "type_cases" + c: ClassVar[FieldProxy] = FieldProxy() username: str @@ -101,7 +106,9 @@ class TypeTestModel(UUIDMixin, ActiveRecord): Python 3.12+ version using | syntax, Self type, and @override. """ - __table_name__ = "type_tests" + @classmethod + def table_name(cls): + return "type_tests" # UUID primary key provided by UUIDMixin string_field: str = Field(default="test string") @@ -119,7 +126,10 @@ class AsyncTypeTestModel(UUIDMixin, AsyncActiveRecord): Python 3.12+ version using | syntax, Self type, and @override. """ - __table_name__ = "type_tests" + @classmethod + def table_name(cls): + return "type_tests" + c: ClassVar[FieldProxy] = FieldProxy() # UUID primary key provided by UUIDMixin @@ -138,7 +148,10 @@ class User(IntegerPKMixin, TimestampMixin, ActiveRecord): Python 3.12+ version using | syntax, Self type, and @override. """ - __table_name__ = "users" + @classmethod + def table_name(cls): + return "users" + c: ClassVar[FieldProxy] = FieldProxy() id: int | None = None @@ -170,7 +183,10 @@ class AsyncUser(IntegerPKMixin, TimestampMixin, AsyncActiveRecord): Python 3.12+ version using | syntax, Self type, and @override. """ - __table_name__ = "users" + @classmethod + def table_name(cls): + return "users" + c: ClassVar[FieldProxy] = FieldProxy() id: int | None = None @@ -193,7 +209,10 @@ class ValidatedFieldUser(IntegerPKMixin, ActiveRecord): Python 3.12+ version using | syntax, Self type, and @override. """ - __table_name__ = "validated_field_users" + @classmethod + def table_name(cls): + return "validated_field_users" + c: ClassVar[FieldProxy] = FieldProxy() id: int | None = None @@ -226,7 +245,10 @@ class AsyncValidatedFieldUser(IntegerPKMixin, AsyncActiveRecord): Python 3.12+ version using | syntax, Self type, and @override. """ - __table_name__ = "validated_field_users" + @classmethod + def table_name(cls): + return "validated_field_users" + c: ClassVar[FieldProxy] = FieldProxy() id: int | None = None @@ -258,7 +280,9 @@ class ValidatedUser(IntegerPKMixin, ActiveRecord): Python 3.12+ version using | syntax, Self type, and @override. """ - __table_name__ = "validated_users" + @classmethod + def table_name(cls): + return "validated_users" id: int | None = None username: str = Field(..., min_length=3, max_length=50) @@ -286,7 +310,10 @@ class AsyncValidatedUser(IntegerPKMixin, AsyncActiveRecord): Python 3.12+ version using | syntax, Self type, and @override. """ - __table_name__ = "validated_users" + @classmethod + def table_name(cls): + return "validated_users" + c: ClassVar[FieldProxy] = FieldProxy() id: int | None = None @@ -345,14 +372,18 @@ def validate_period(self): class PydanticValidatedModel(PydanticValidatedFieldsMixin, IntegerPKMixin, ActiveRecord): """Model for Pydantic native validation contract tests.""" - __table_name__ = "pydantic_validated_models" + @classmethod + def table_name(cls): + return "pydantic_validated_models" id: int | None = None class AsyncPydanticValidatedModel(PydanticValidatedFieldsMixin, IntegerPKMixin, AsyncActiveRecord): """Async model for Pydantic native validation contract tests.""" - __table_name__ = "pydantic_validated_models" + @classmethod + def table_name(cls): + return "pydantic_validated_models" id: int | None = None @@ -371,7 +402,9 @@ class TypeAdapterTest(ActiveRecord): Python 3.12+ version using | syntax. """ - __table_name__ = 'type_adapter_tests' + @classmethod + def table_name(cls): + return 'type_adapter_tests' id: int | None = None name: str @@ -389,7 +422,10 @@ class AsyncTypeAdapterTest(AsyncActiveRecord): Python 3.12+ version using | syntax. """ - __table_name__ = 'type_adapter_tests' + @classmethod + def table_name(cls): + return 'type_adapter_tests' + c: ClassVar[FieldProxy] = FieldProxy() id: int | None = None @@ -408,7 +444,9 @@ class MappedUser(IntegerPKMixin, TimestampMixin, ActiveRecord): Python 3.12+ version using | syntax, Self type, and @override. """ - __table_name__ = "users" + @classmethod + def table_name(cls): + return "users" user_id: Annotated[int | None, UseColumn("id")] = None user_name: Annotated[str, UseColumn("username")] @@ -426,7 +464,10 @@ class AsyncMappedUser(IntegerPKMixin, TimestampMixin, AsyncActiveRecord): Python 3.12+ version using | syntax. """ - __table_name__ = "users" + @classmethod + def table_name(cls): + return "users" + c: ClassVar[FieldProxy] = FieldProxy() user_id: Annotated[int | None, UseColumn("id")] = None @@ -440,7 +481,9 @@ class MappedPost(IntegerPKMixin, TimestampMixin, ActiveRecord): Python 3.12+ version using | syntax. """ - __table_name__ = "posts" + @classmethod + def table_name(cls): + return "posts" post_id: Annotated[int | None, UseColumn("id")] = None author_id: Annotated[int, UseColumn("author")] @@ -455,7 +498,10 @@ class AsyncMappedPost(IntegerPKMixin, TimestampMixin, AsyncActiveRecord): Python 3.12+ version using | syntax. """ - __table_name__ = "posts" + @classmethod + def table_name(cls): + return "posts" + c: ClassVar[FieldProxy] = FieldProxy() post_id: Annotated[int | None, UseColumn("id")] = None @@ -471,7 +517,9 @@ class MappedComment(IntegerPKMixin, TimestampMixin, ActiveRecord): Python 3.12+ version using | syntax. """ - __table_name__ = "comments" + @classmethod + def table_name(cls): + return "comments" comment_id: Annotated[int | None, UseColumn("id")] = None post_id: Annotated[int, UseColumn("post_ref")] @@ -486,7 +534,10 @@ class AsyncMappedComment(IntegerPKMixin, TimestampMixin, AsyncActiveRecord): Python 3.12+ version using | syntax. """ - __table_name__ = "comments" + @classmethod + def table_name(cls): + return "comments" + c: ClassVar[FieldProxy] = FieldProxy() comment_id: Annotated[int | None, UseColumn("id")] = None @@ -516,7 +567,9 @@ class ColumnMappingModel(ActiveRecord): Python 3.12+ version using | syntax. """ - __table_name__ = 'column_mapping_items' + @classmethod + def table_name(cls): + return 'column_mapping_items' item_id: Annotated[int | None, UseColumn("id")] = Field(default=None) name: str @@ -529,7 +582,10 @@ class AsyncColumnMappingModel(AsyncActiveRecord): Python 3.12+ version using | syntax. """ - __table_name__ = 'column_mapping_items' + @classmethod + def table_name(cls): + return 'column_mapping_items' + c: ClassVar[FieldProxy] = FieldProxy() item_id: Annotated[int | None, UseColumn("id")] = Field(default=None) @@ -607,7 +663,9 @@ class MixedAnnotationModel(ActiveRecord): Python 3.12+ version using | syntax, Self type, and @override. """ - __table_name__ = "mixed_annotation_items" + @classmethod + def table_name(cls): + return "mixed_annotation_items" name: str item_id: Annotated[int, UseColumn("id")] @@ -628,7 +686,10 @@ class AsyncMixedAnnotationModel(AsyncActiveRecord): Python 3.12+ version using | syntax. """ - __table_name__ = "mixed_annotation_items" + @classmethod + def table_name(cls): + return "mixed_annotation_items" + c: ClassVar[FieldProxy] = FieldProxy() name: str @@ -694,8 +755,14 @@ def unwrap(self) -> T: class OrderItem(CompositePKMixin, ActiveRecord): """Composite PK (order_id, product_id), PK provided by application.""" - __table_name__ = "order_items" - __primary_key__ = ("order_id", "product_id") + @classmethod + def table_name(cls): + return "order_items" + + @classmethod + def primary_key(cls): + return ("order_id", "product_id") + c: ClassVar[FieldProxy] = FieldProxy() order_id: int @@ -706,8 +773,14 @@ class OrderItem(CompositePKMixin, ActiveRecord): class AsyncOrderItem(CompositePKMixin, AsyncActiveRecord): """Async variant of OrderItem.""" - __table_name__ = "order_items" - __primary_key__ = ("order_id", "product_id") + @classmethod + def table_name(cls): + return "order_items" + + @classmethod + def primary_key(cls): + return ("order_id", "product_id") + c: ClassVar[FieldProxy] = FieldProxy() order_id: int @@ -718,8 +791,14 @@ class AsyncOrderItem(CompositePKMixin, AsyncActiveRecord): class StoreInventory(CompositePKMixin, ActiveRecord): """Triple-column composite PK.""" - __table_name__ = "store_inventory" - __primary_key__ = ("store_id", "product_id", "batch_id") + @classmethod + def table_name(cls): + return "store_inventory" + + @classmethod + def primary_key(cls): + return ("store_id", "product_id", "batch_id") + c: ClassVar[FieldProxy] = FieldProxy() store_id: int @@ -730,8 +809,14 @@ class StoreInventory(CompositePKMixin, ActiveRecord): class AsyncStoreInventory(CompositePKMixin, AsyncActiveRecord): """Async variant of StoreInventory.""" - __table_name__ = "store_inventory" - __primary_key__ = ("store_id", "product_id", "batch_id") + @classmethod + def table_name(cls): + return "store_inventory" + + @classmethod + def primary_key(cls): + return ("store_id", "product_id", "batch_id") + c: ClassVar[FieldProxy] = FieldProxy() store_id: int @@ -742,7 +827,10 @@ class AsyncStoreInventory(CompositePKMixin, AsyncActiveRecord): class Order(IntegerPKMixin, TimestampMixin, ActiveRecord): """Single-column auto-increment PK -- backward compatibility control group.""" - __table_name__ = "orders" + @classmethod + def table_name(cls): + return "orders" + c: ClassVar[FieldProxy] = FieldProxy() id: Optional[int] = None @@ -751,7 +839,10 @@ class Order(IntegerPKMixin, TimestampMixin, ActiveRecord): class AsyncOrder(IntegerPKMixin, TimestampMixin, AsyncActiveRecord): """Async variant of Order.""" - __table_name__ = "orders" + @classmethod + def table_name(cls): + return "orders" + c: ClassVar[FieldProxy] = FieldProxy() id: Optional[int] = None @@ -760,8 +851,13 @@ class AsyncOrder(IntegerPKMixin, TimestampMixin, AsyncActiveRecord): class MappedOrderItem(CompositePKMixin, ActiveRecord): """Composite PK with UseColumn mapping -- Python field names differ from DB column names.""" - __table_name__ = "order_items" - __primary_key__ = ("order_id", "product_id") + @classmethod + def table_name(cls): + return "order_items" + + @classmethod + def primary_key(cls): + return ("order_id", "product_id") order_ref: Annotated[int, UseColumn("order_id")] product_ref: Annotated[int, UseColumn("product_id")] @@ -771,8 +867,14 @@ class MappedOrderItem(CompositePKMixin, ActiveRecord): class AsyncMappedOrderItem(CompositePKMixin, AsyncActiveRecord): """Async variant of MappedOrderItem.""" - __table_name__ = "order_items" - __primary_key__ = ("order_id", "product_id") + @classmethod + def table_name(cls): + return "order_items" + + @classmethod + def primary_key(cls): + return ("order_id", "product_id") + c: ClassVar[FieldProxy] = FieldProxy() order_ref: Annotated[int, UseColumn("order_id")] @@ -782,7 +884,10 @@ class AsyncMappedOrderItem(CompositePKMixin, AsyncActiveRecord): class BulkUser(IntegerPKMixin, ActiveRecord): - __table_name__ = "bulk_users" + @classmethod + def table_name(cls): + return "bulk_users" + c: ClassVar[FieldProxy] = FieldProxy() id: int | None = None @@ -792,7 +897,10 @@ class BulkUser(IntegerPKMixin, ActiveRecord): class AsyncBulkUser(IntegerPKMixin, AsyncActiveRecord): - __table_name__ = "bulk_users" + @classmethod + def table_name(cls): + return "bulk_users" + c: ClassVar[FieldProxy] = FieldProxy() id: int | None = None diff --git a/tests/rhosocial/activerecord_mysql_test/feature/events/fixtures/models.py b/tests/rhosocial/activerecord_mysql_test/feature/events/fixtures/models.py index 5d7d69f9..93c60919 100644 --- a/tests/rhosocial/activerecord_mysql_test/feature/events/fixtures/models.py +++ b/tests/rhosocial/activerecord_mysql_test/feature/events/fixtures/models.py @@ -19,7 +19,9 @@ class EventTestModel(IntegerPKMixin, TimestampMixin, ActiveRecord): """A model class for testing event mechanisms""" - __table_name__ = "event_tests" + @classmethod + def table_name(cls): + return "event_tests" id: Optional[int] = None name: str @@ -46,7 +48,9 @@ def clear_event_logs(self): class AsyncEventTestModel(IntegerPKMixin, TimestampMixin, AsyncActiveRecord): """An async model class for testing event mechanisms""" - __table_name__ = "event_tests" + @classmethod + def table_name(cls): + return "event_tests" id: Optional[int] = None name: str @@ -73,7 +77,9 @@ def clear_event_logs(self): class EventTrackingModel(IntegerPKMixin, ActiveRecord): """A model for testing event tracking functionality.""" - __table_name__ = "event_tracking_models" + @classmethod + def table_name(cls): + return "event_tracking_models" title: str content: str diff --git a/tests/rhosocial/activerecord_mysql_test/feature/events/fixtures/models_py310.py b/tests/rhosocial/activerecord_mysql_test/feature/events/fixtures/models_py310.py index 0e9dba08..bd3ee5e0 100644 --- a/tests/rhosocial/activerecord_mysql_test/feature/events/fixtures/models_py310.py +++ b/tests/rhosocial/activerecord_mysql_test/feature/events/fixtures/models_py310.py @@ -8,7 +8,7 @@ Note: This file should only be imported and used in Python 3.10+ environments. """ -from typing import Dict, List, Tuple +from typing import Dict from datetime import datetime from pydantic import Field @@ -27,7 +27,9 @@ class EventTestModel(IntegerPKMixin, TimestampMixin, ActiveRecord): Python 3.10+ version using | syntax instead of Optional. """ - __table_name__ = "event_tests" + @classmethod + def table_name(cls): + return "event_tests" id: int | None = None name: str @@ -57,7 +59,9 @@ class EventTrackingModel(IntegerPKMixin, ActiveRecord): Python 3.10+ version using | syntax instead of Optional. """ - __table_name__ = "event_tracking_models" + @classmethod + def table_name(cls): + return "event_tracking_models" title: str content: str diff --git a/tests/rhosocial/activerecord_mysql_test/feature/events/fixtures/models_py311.py b/tests/rhosocial/activerecord_mysql_test/feature/events/fixtures/models_py311.py index f48aa467..786f4f32 100644 --- a/tests/rhosocial/activerecord_mysql_test/feature/events/fixtures/models_py311.py +++ b/tests/rhosocial/activerecord_mysql_test/feature/events/fixtures/models_py311.py @@ -29,7 +29,9 @@ class EventTestModel(IntegerPKMixin, TimestampMixin, ActiveRecord): Python 3.11+ version using | syntax and Self type. """ - __table_name__ = "event_tests" + @classmethod + def table_name(cls): + return "event_tests" id: int | None = None name: str @@ -70,7 +72,9 @@ class EventTrackingModel(IntegerPKMixin, ActiveRecord): Python 3.11+ version using | syntax and Self type. """ - __table_name__ = "event_tracking_models" + @classmethod + def table_name(cls): + return "event_tracking_models" title: str content: str diff --git a/tests/rhosocial/activerecord_mysql_test/feature/events/fixtures/models_py312.py b/tests/rhosocial/activerecord_mysql_test/feature/events/fixtures/models_py312.py index f4b82d02..9196e1a0 100644 --- a/tests/rhosocial/activerecord_mysql_test/feature/events/fixtures/models_py312.py +++ b/tests/rhosocial/activerecord_mysql_test/feature/events/fixtures/models_py312.py @@ -11,7 +11,7 @@ """ from __future__ import annotations -from typing import Dict, Self, override +from typing import Dict, Self from datetime import datetime from pydantic import Field @@ -30,7 +30,9 @@ class EventTestModel(IntegerPKMixin, TimestampMixin, ActiveRecord): Python 3.12+ version using | syntax, Self type, and @override. """ - __table_name__ = "event_tests" + @classmethod + def table_name(cls): + return "event_tests" id: int | None = None name: str @@ -71,7 +73,9 @@ class EventTrackingModel(IntegerPKMixin, ActiveRecord): Python 3.12+ version using | syntax, Self type, and @override. """ - __table_name__ = "event_tracking_models" + @classmethod + def table_name(cls): + return "event_tracking_models" title: str content: str diff --git a/tests/rhosocial/activerecord_mysql_test/feature/mixins/fixtures/models.py b/tests/rhosocial/activerecord_mysql_test/feature/mixins/fixtures/models.py index 922ffd14..921aa249 100644 --- a/tests/rhosocial/activerecord_mysql_test/feature/mixins/fixtures/models.py +++ b/tests/rhosocial/activerecord_mysql_test/feature/mixins/fixtures/models.py @@ -8,7 +8,6 @@ configuring them with a live database connection at test time. """ from typing import Optional -from datetime import datetime from pydantic import Field @@ -18,7 +17,9 @@ class TimestampedPost(IntegerPKMixin, TimestampMixin, ActiveRecord): """Blog post model with timestamps""" - __table_name__ = "timestamped_posts" + @classmethod + def table_name(cls): + return "timestamped_posts" id: Optional[int] = None title: str @@ -27,7 +28,9 @@ class TimestampedPost(IntegerPKMixin, TimestampMixin, ActiveRecord): class VersionedProduct(IntegerPKMixin, OptimisticLockMixin, ActiveRecord): """Product model with optimistic locking""" - __table_name__ = "versioned_products" + @classmethod + def table_name(cls): + return "versioned_products" id: Optional[int] = None name: str @@ -36,7 +39,9 @@ class VersionedProduct(IntegerPKMixin, OptimisticLockMixin, ActiveRecord): class Task(IntegerPKMixin, SoftDeleteMixin, ActiveRecord): """Task model supporting soft deletion""" - __table_name__ = "tasks" + @classmethod + def table_name(cls): + return "tasks" id: Optional[int] = None title: str @@ -45,7 +50,9 @@ class Task(IntegerPKMixin, SoftDeleteMixin, ActiveRecord): class CombinedArticle(IntegerPKMixin, TimestampMixin, OptimisticLockMixin, SoftDeleteMixin, ActiveRecord): """Article model combining all mixins""" - __table_name__ = "combined_articles" + @classmethod + def table_name(cls): + return "combined_articles" id: Optional[int] = None title: str @@ -55,7 +62,9 @@ class CombinedArticle(IntegerPKMixin, TimestampMixin, OptimisticLockMixin, SoftD class AsyncTimestampedPost(IntegerPKMixin, TimestampMixin, AsyncActiveRecord): """Blog post model with timestamps (async version)""" - __table_name__ = "timestamped_posts" + @classmethod + def table_name(cls): + return "timestamped_posts" id: Optional[int] = None title: str @@ -64,7 +73,9 @@ class AsyncTimestampedPost(IntegerPKMixin, TimestampMixin, AsyncActiveRecord): class AsyncVersionedProduct(IntegerPKMixin, OptimisticLockMixin, AsyncActiveRecord): """Product model with optimistic locking (async version)""" - __table_name__ = "versioned_products" + @classmethod + def table_name(cls): + return "versioned_products" id: Optional[int] = None name: str @@ -73,7 +84,9 @@ class AsyncVersionedProduct(IntegerPKMixin, OptimisticLockMixin, AsyncActiveReco class AsyncTask(IntegerPKMixin, AsyncSoftDeleteMixin, AsyncActiveRecord): """Task model supporting soft deletion (async version)""" - __table_name__ = "tasks" + @classmethod + def table_name(cls): + return "tasks" id: Optional[int] = None title: str @@ -82,7 +95,9 @@ class AsyncTask(IntegerPKMixin, AsyncSoftDeleteMixin, AsyncActiveRecord): class AsyncCombinedArticle(IntegerPKMixin, TimestampMixin, OptimisticLockMixin, AsyncSoftDeleteMixin, AsyncActiveRecord): """Article model combining all mixins (async version)""" - __table_name__ = "combined_articles" + @classmethod + def table_name(cls): + return "combined_articles" id: Optional[int] = None title: str diff --git a/tests/rhosocial/activerecord_mysql_test/feature/mixins/fixtures/models_py310.py b/tests/rhosocial/activerecord_mysql_test/feature/mixins/fixtures/models_py310.py index c587ccce..b7d0778e 100644 --- a/tests/rhosocial/activerecord_mysql_test/feature/mixins/fixtures/models_py310.py +++ b/tests/rhosocial/activerecord_mysql_test/feature/mixins/fixtures/models_py310.py @@ -8,7 +8,6 @@ Note: This file should only be imported and used in Python 3.10+ environments. """ -from datetime import datetime from pydantic import Field @@ -25,7 +24,9 @@ class TimestampedPost(IntegerPKMixin, TimestampMixin, ActiveRecord): Python 3.10+ version using | syntax instead of Optional. """ - __table_name__ = "timestamped_posts" + @classmethod + def table_name(cls): + return "timestamped_posts" id: int | None = None title: str @@ -37,7 +38,9 @@ class VersionedProduct(IntegerPKMixin, OptimisticLockMixin, ActiveRecord): Python 3.10+ version using | syntax instead of Optional. """ - __table_name__ = "versioned_products" + @classmethod + def table_name(cls): + return "versioned_products" id: int | None = None name: str @@ -49,7 +52,9 @@ class Task(IntegerPKMixin, SoftDeleteMixin, ActiveRecord): Python 3.10+ version using | syntax instead of Optional. """ - __table_name__ = "tasks" + @classmethod + def table_name(cls): + return "tasks" id: int | None = None title: str @@ -61,7 +66,9 @@ class CombinedArticle(IntegerPKMixin, TimestampMixin, OptimisticLockMixin, SoftD Python 3.10+ version using | syntax instead of Optional. """ - __table_name__ = "combined_articles" + @classmethod + def table_name(cls): + return "combined_articles" id: int | None = None title: str diff --git a/tests/rhosocial/activerecord_mysql_test/feature/mixins/fixtures/models_py311.py b/tests/rhosocial/activerecord_mysql_test/feature/mixins/fixtures/models_py311.py index 6a8798c3..978afa7f 100644 --- a/tests/rhosocial/activerecord_mysql_test/feature/mixins/fixtures/models_py311.py +++ b/tests/rhosocial/activerecord_mysql_test/feature/mixins/fixtures/models_py311.py @@ -10,7 +10,6 @@ """ from __future__ import annotations -from datetime import datetime from typing import Self from pydantic import Field @@ -28,7 +27,9 @@ class TimestampedPost(IntegerPKMixin, TimestampMixin, ActiveRecord): Python 3.11+ version using | syntax and Self type. """ - __table_name__ = "timestamped_posts" + @classmethod + def table_name(cls): + return "timestamped_posts" id: int | None = None title: str @@ -45,7 +46,9 @@ class VersionedProduct(IntegerPKMixin, OptimisticLockMixin, ActiveRecord): Python 3.11+ version using | syntax and Self type. """ - __table_name__ = "versioned_products" + @classmethod + def table_name(cls): + return "versioned_products" id: int | None = None name: str @@ -62,7 +65,9 @@ class Task(IntegerPKMixin, SoftDeleteMixin, ActiveRecord): Python 3.11+ version using | syntax and Self type. """ - __table_name__ = "tasks" + @classmethod + def table_name(cls): + return "tasks" id: int | None = None title: str @@ -84,7 +89,9 @@ class CombinedArticle(IntegerPKMixin, TimestampMixin, OptimisticLockMixin, SoftD Python 3.11+ version using | syntax and Self type. """ - __table_name__ = "combined_articles" + @classmethod + def table_name(cls): + return "combined_articles" id: int | None = None title: str diff --git a/tests/rhosocial/activerecord_mysql_test/feature/mixins/fixtures/models_py312.py b/tests/rhosocial/activerecord_mysql_test/feature/mixins/fixtures/models_py312.py index 36ccbe31..176fabe4 100644 --- a/tests/rhosocial/activerecord_mysql_test/feature/mixins/fixtures/models_py312.py +++ b/tests/rhosocial/activerecord_mysql_test/feature/mixins/fixtures/models_py312.py @@ -11,7 +11,6 @@ """ from __future__ import annotations -from datetime import datetime from typing import Self, override from pydantic import Field @@ -29,7 +28,9 @@ class TimestampedPost(IntegerPKMixin, TimestampMixin, ActiveRecord): Python 3.12+ version using | syntax, Self type, and @override. """ - __table_name__ = "timestamped_posts" + @classmethod + def table_name(cls): + return "timestamped_posts" id: int | None = None title: str @@ -52,7 +53,9 @@ class VersionedProduct(IntegerPKMixin, OptimisticLockMixin, ActiveRecord): Python 3.12+ version using | syntax, Self type, and @override. """ - __table_name__ = "versioned_products" + @classmethod + def table_name(cls): + return "versioned_products" id: int | None = None name: str @@ -75,7 +78,9 @@ class Task(IntegerPKMixin, SoftDeleteMixin, ActiveRecord): Python 3.12+ version using | syntax, Self type, and @override. """ - __table_name__ = "tasks" + @classmethod + def table_name(cls): + return "tasks" id: int | None = None title: str @@ -103,7 +108,9 @@ class CombinedArticle(IntegerPKMixin, TimestampMixin, OptimisticLockMixin, SoftD Python 3.12+ version using | syntax, Self type, and @override. """ - __table_name__ = "combined_articles" + @classmethod + def table_name(cls): + return "combined_articles" id: int | None = None title: str diff --git a/tests/rhosocial/activerecord_mysql_test/feature/relation/fixtures/models.py b/tests/rhosocial/activerecord_mysql_test/feature/relation/fixtures/models.py index 955cab2c..3149a627 100644 --- a/tests/rhosocial/activerecord_mysql_test/feature/relation/fixtures/models.py +++ b/tests/rhosocial/activerecord_mysql_test/feature/relation/fixtures/models.py @@ -15,7 +15,7 @@ from rhosocial.activerecord.base import DerivedField, FieldProxy from rhosocial.activerecord.backend.expression import ArithmeticOperation, Column, Literal from rhosocial.activerecord.backend.expression.functions import ( - json_extract_text, length, concat, coalesce + json_extract_text, length, coalesce ) from rhosocial.activerecord.relation.descriptors import BelongsTo, HasMany, HasOne from rhosocial.activerecord.relation.async_descriptors import AsyncBelongsTo, AsyncHasMany, AsyncHasOne @@ -24,7 +24,9 @@ # ── Basic Relation Models ──────────────────────────────── class Employee(ActiveRecord): - __table_name__ = "employees" + @classmethod + def table_name(cls): + return "employees" id: Optional[int] = None username: str @@ -37,7 +39,9 @@ class Employee(ActiveRecord): class Department(ActiveRecord): - __table_name__ = "departments" + @classmethod + def table_name(cls): + return "departments" id: Optional[int] = None name: str @@ -50,7 +54,9 @@ class Department(ActiveRecord): class Author(ActiveRecord): - __table_name__ = "authors" + @classmethod + def table_name(cls): + return "authors" id: Optional[int] = None name: str @@ -66,7 +72,9 @@ class Author(ActiveRecord): class Book(ActiveRecord): - __table_name__ = "books" + @classmethod + def table_name(cls): + return "books" id: Optional[int] = None title: str @@ -83,7 +91,9 @@ class Book(ActiveRecord): class Chapter(ActiveRecord): - __table_name__ = "chapters" + @classmethod + def table_name(cls): + return "chapters" id: Optional[int] = None title: str @@ -96,7 +106,9 @@ class Chapter(ActiveRecord): class Profile(ActiveRecord): - __table_name__ = "profiles" + @classmethod + def table_name(cls): + return "profiles" id: Optional[int] = None bio: str @@ -111,7 +123,9 @@ class Profile(ActiveRecord): # ── Advanced Relation Models (with FieldProxy, DerivedField, JSON) ── class User(ActiveRecord): - __table_name__ = "users" + @classmethod + def table_name(cls): + return "users" c: ClassVar[FieldProxy] = FieldProxy() id: Optional[int] = None @@ -142,7 +156,9 @@ class User(ActiveRecord): class Post(ActiveRecord): - __table_name__ = "posts" + @classmethod + def table_name(cls): + return "posts" c: ClassVar[FieldProxy] = FieldProxy() id: Optional[int] = None @@ -184,7 +200,9 @@ class Post(ActiveRecord): class Comment(ActiveRecord): - __table_name__ = "comments" + @classmethod + def table_name(cls): + return "comments" c: ClassVar[FieldProxy] = FieldProxy() id: Optional[int] = None @@ -212,7 +230,9 @@ class Comment(ActiveRecord): # ── Async Models ───────────────────────────────────────── class AsyncUser(AsyncActiveRecord): - __table_name__ = "users" + @classmethod + def table_name(cls): + return "users" c: ClassVar[FieldProxy] = FieldProxy() id: Optional[int] = None @@ -239,7 +259,9 @@ class AsyncUser(AsyncActiveRecord): class AsyncPost(AsyncActiveRecord): - __table_name__ = "posts" + @classmethod + def table_name(cls): + return "posts" c: ClassVar[FieldProxy] = FieldProxy() id: Optional[int] = None @@ -276,7 +298,9 @@ class AsyncPost(AsyncActiveRecord): class AsyncComment(AsyncActiveRecord): - __table_name__ = "comments" + @classmethod + def table_name(cls): + return "comments" c: ClassVar[FieldProxy] = FieldProxy() id: Optional[int] = None @@ -301,7 +325,9 @@ class AsyncComment(AsyncActiveRecord): # ── Relation Boundary Models ────────────────────────────── class BoundaryOwner(ActiveRecord): - __table_name__ = "relation_boundary_owners" + @classmethod + def table_name(cls): + return "relation_boundary_owners" id: Optional[int] = None name: str @@ -317,7 +343,9 @@ class BoundaryOwner(ActiveRecord): class BoundaryProfile(ActiveRecord): - __table_name__ = "relation_boundary_profiles" + @classmethod + def table_name(cls): + return "relation_boundary_profiles" id: Optional[int] = None bio: str @@ -330,7 +358,9 @@ class BoundaryProfile(ActiveRecord): class BoundaryPost(ActiveRecord): - __table_name__ = "relation_boundary_posts" + @classmethod + def table_name(cls): + return "relation_boundary_posts" id: Optional[int] = None title: str @@ -343,7 +373,9 @@ class BoundaryPost(ActiveRecord): class AsyncBoundaryOwner(AsyncActiveRecord): - __table_name__ = "relation_boundary_owners" + @classmethod + def table_name(cls): + return "relation_boundary_owners" id: Optional[int] = None name: str @@ -359,7 +391,9 @@ class AsyncBoundaryOwner(AsyncActiveRecord): class AsyncBoundaryProfile(AsyncActiveRecord): - __table_name__ = "relation_boundary_profiles" + @classmethod + def table_name(cls): + return "relation_boundary_profiles" id: Optional[int] = None bio: str @@ -372,7 +406,9 @@ class AsyncBoundaryProfile(AsyncActiveRecord): class AsyncBoundaryPost(AsyncActiveRecord): - __table_name__ = "relation_boundary_posts" + @classmethod + def table_name(cls): + return "relation_boundary_posts" id: Optional[int] = None title: str diff --git a/tests/rhosocial/activerecord_mysql_test/feature/relation/fixtures/models_py310.py b/tests/rhosocial/activerecord_mysql_test/feature/relation/fixtures/models_py310.py index 20e10165..e91bf2c1 100644 --- a/tests/rhosocial/activerecord_mysql_test/feature/relation/fixtures/models_py310.py +++ b/tests/rhosocial/activerecord_mysql_test/feature/relation/fixtures/models_py310.py @@ -22,7 +22,9 @@ class Employee(ActiveRecord): Python 3.10+ version. """ - __table_name__ = "employees" + @classmethod + def table_name(cls): + return "employees" id: int | None = None username: str @@ -40,7 +42,9 @@ class Department(ActiveRecord): Python 3.10+ version. """ - __table_name__ = "departments" + @classmethod + def table_name(cls): + return "departments" id: int | None = None name: str @@ -58,7 +62,9 @@ class Author(ActiveRecord): Python 3.10+ version. """ - __table_name__ = "authors" + @classmethod + def table_name(cls): + return "authors" id: int | None = None name: str @@ -79,7 +85,9 @@ class Book(ActiveRecord): Python 3.10+ version. """ - __table_name__ = "books" + @classmethod + def table_name(cls): + return "books" id: int | None = None title: str @@ -101,7 +109,9 @@ class Chapter(ActiveRecord): Python 3.10+ version. """ - __table_name__ = "chapters" + @classmethod + def table_name(cls): + return "chapters" id: int | None = None title: str @@ -119,7 +129,9 @@ class Profile(ActiveRecord): Python 3.10+ version. """ - __table_name__ = "profiles" + @classmethod + def table_name(cls): + return "profiles" id: int | None = None bio: str diff --git a/tests/rhosocial/activerecord_mysql_test/feature/relation/fixtures/models_py311.py b/tests/rhosocial/activerecord_mysql_test/feature/relation/fixtures/models_py311.py index a6835c3a..ea692f3c 100644 --- a/tests/rhosocial/activerecord_mysql_test/feature/relation/fixtures/models_py311.py +++ b/tests/rhosocial/activerecord_mysql_test/feature/relation/fixtures/models_py311.py @@ -25,7 +25,9 @@ class Employee(ActiveRecord): Python 3.11+ version using | syntax and Self type. """ - __table_name__ = "employees" + @classmethod + def table_name(cls): + return "employees" id: int | None = None username: str @@ -48,7 +50,9 @@ class Department(ActiveRecord): Python 3.11+ version using | syntax and Self type. """ - __table_name__ = "departments" + @classmethod + def table_name(cls): + return "departments" id: int | None = None name: str @@ -71,7 +75,9 @@ class Author(ActiveRecord): Python 3.11+ version using | syntax and Self type. """ - __table_name__ = "authors" + @classmethod + def table_name(cls): + return "authors" id: int | None = None name: str @@ -97,7 +103,9 @@ class Book(ActiveRecord): Python 3.11+ version using | syntax and Self type. """ - __table_name__ = "books" + @classmethod + def table_name(cls): + return "books" id: int | None = None title: str @@ -124,7 +132,9 @@ class Chapter(ActiveRecord): Python 3.11+ version using | syntax and Self type. """ - __table_name__ = "chapters" + @classmethod + def table_name(cls): + return "chapters" id: int | None = None title: str @@ -147,7 +157,9 @@ class Profile(ActiveRecord): Python 3.11+ version using | syntax and Self type. """ - __table_name__ = "profiles" + @classmethod + def table_name(cls): + return "profiles" id: int | None = None bio: str diff --git a/tests/rhosocial/activerecord_mysql_test/feature/relation/fixtures/models_py312.py b/tests/rhosocial/activerecord_mysql_test/feature/relation/fixtures/models_py312.py index 84ce68c8..75a3906f 100644 --- a/tests/rhosocial/activerecord_mysql_test/feature/relation/fixtures/models_py312.py +++ b/tests/rhosocial/activerecord_mysql_test/feature/relation/fixtures/models_py312.py @@ -26,7 +26,9 @@ class Employee(ActiveRecord): Python 3.12+ version using | syntax, Self type, and @override. """ - __table_name__ = "employees" + @classmethod + def table_name(cls): + return "employees" id: int | None = None username: str @@ -55,7 +57,9 @@ class Department(ActiveRecord): Python 3.12+ version using | syntax, Self type, and @override. """ - __table_name__ = "departments" + @classmethod + def table_name(cls): + return "departments" id: int | None = None name: str @@ -84,7 +88,9 @@ class Author(ActiveRecord): Python 3.12+ version using | syntax, Self type, and @override. """ - __table_name__ = "authors" + @classmethod + def table_name(cls): + return "authors" id: int | None = None name: str @@ -116,7 +122,9 @@ class Book(ActiveRecord): Python 3.12+ version using | syntax, Self type, and @override. """ - __table_name__ = "books" + @classmethod + def table_name(cls): + return "books" id: int | None = None title: str @@ -149,7 +157,9 @@ class Chapter(ActiveRecord): Python 3.12+ version using | syntax, Self type, and @override. """ - __table_name__ = "chapters" + @classmethod + def table_name(cls): + return "chapters" id: int | None = None title: str @@ -178,7 +188,9 @@ class Profile(ActiveRecord): Python 3.12+ version using | syntax, Self type, and @override. """ - __table_name__ = "profiles" + @classmethod + def table_name(cls): + return "profiles" id: int | None = None bio: str