diff --git a/.check_expression_baseline.json b/.check_expression_baseline.json new file mode 100644 index 0000000..866a73d --- /dev/null +++ b/.check_expression_baseline.json @@ -0,0 +1,338 @@ +{ + "entries": { + "026ace9a84110350": 4, + "08634c72c7c03ffd": 1, + "101e4e4ceaf350c2": 1, + "10b329845f0a95e1": 1, + "229b011f5326852a": 1, + "27e1690b06964630": 1, + "285d9c5405fcd9be": 1, + "2aefe6ab12519a69": 2, + "328190b943908678": 1, + "35f151866fd2651c": 1, + "3929e20fec133d8c": 1, + "582274b3d3e7fc7d": 1, + "5a73d2dc16bed3bb": 1, + "67c56830f44cac3c": 1, + "6bbb1e98a9ffa49b": 1, + "7c38ab02e49d6163": 1, + "8132a551dac6d30f": 1, + "84d77124137947d7": 1, + "8541f179750ff3e4": 1, + "890c8c39d0ccc05f": 2, + "8fcccebae913b0f2": 1, + "9a2939ab62d884b6": 1, + "9ba5cf8c8342b987": 1, + "9fa9e594ac9ad72a": 1, + "a364172778448536": 1, + "a66353108ab90fd1": 1, + "b49dfcb296596f61": 1, + "bc1426a305c31762": 1, + "c0c7daaefb145ef8": 1, + "c8b203e065d56f04": 1, + "ca66f9dc69f5df00": 1, + "d4aeca39d6235650": 1, + "d9ec27a02a72eea8": 1, + "dc15d9bf96e96abc": 2, + "e430c99cc97b4b34": 1, + "e8de5da02bd250a1": 1, + "f2d496e0cad2c2f3": 11, + "fd7c4fd11c523124": 1, + "fed74ba84bcc339d": 1, + "ff4e2a4b2db9cb63": 1, + "fffd502e479e25c2": 2 + }, + "findings": [ + { + "found": "if_not_exists: Optional[bool]", + "path": "src/rhosocial/activerecord/backend/impl/clickhouse/expression/alter_column.py", + "rule": "ED-10.2" + }, + { + "found": "kwargs: Any", + "path": "src/rhosocial/activerecord/backend/impl/clickhouse/expression/json.py", + "rule": "ED-KWARGS" + }, + { + "found": "getattr(action, \"if_not_exists\", None)", + "path": "src/rhosocial/activerecord/backend/impl/clickhouse/mixins/ddl_column.py", + "rule": "ED-11.2" + }, + { + "found": "getattr(action, \"after\", None)", + "path": "src/rhosocial/activerecord/backend/impl/clickhouse/mixins/ddl_column.py", + "rule": "ED-11.2" + }, + { + "found": "getattr(action.operation, \"value\", None)", + "path": "src/rhosocial/activerecord/backend/impl/clickhouse/mixins/ddl_column.py", + "rule": "ED-11.2" + }, + { + "found": "getattr(action, \"new_value\", None)", + "path": "src/rhosocial/activerecord/backend/impl/clickhouse/mixins/ddl_column.py", + "rule": "ED-11.2" + }, + { + "found": "getattr(expr, \"engine\", None)", + "path": "src/rhosocial/activerecord/backend/impl/clickhouse/mixins/ddl_database.py", + "rule": "ED-11.2" + }, + { + "found": "getattr(expr, \"on_cluster\", None)", + "path": "src/rhosocial/activerecord/backend/impl/clickhouse/mixins/ddl_database.py", + "rule": "ED-11.2" + }, + { + "found": "getattr(expr, \"sync\", False)", + "path": "src/rhosocial/activerecord/backend/impl/clickhouse/mixins/ddl_database.py", + "rule": "ED-11.2" + }, + { + "found": "getattr(expr.action, 'value', expr.action)", + "path": "src/rhosocial/activerecord/backend/impl/clickhouse/mixins/ddl_database.py", + "rule": "ED-11.2" + }, + { + "found": "getattr(expr, \"table_options\", None)", + "path": "src/rhosocial/activerecord/backend/impl/clickhouse/mixins/ddl_table.py", + "rule": "ED-11.2" + }, + { + "found": "getattr(expr, \"table_options\", None)", + "path": "src/rhosocial/activerecord/backend/impl/clickhouse/mixins/ddl_table.py", + "rule": "ED-11.2" + }, + { + "found": "getattr(table_options, \"comment\", None)", + "path": "src/rhosocial/activerecord/backend/impl/clickhouse/mixins/ddl_table.py", + "rule": "ED-11.2" + }, + { + "found": "getattr(t_const, \"foreign_key_table\", None)", + "path": "src/rhosocial/activerecord/backend/impl/clickhouse/mixins/ddl_table.py", + "rule": "ED-11.2" + }, + { + "found": "getattr(expr, \"replace\", False)", + "path": "src/rhosocial/activerecord/backend/impl/clickhouse/mixins/dml.py", + "rule": "ED-11.2" + }, + { + "found": "getattr(expr, \"ignore\", False)", + "path": "src/rhosocial/activerecord/backend/impl/clickhouse/mixins/dml.py", + "rule": "ED-11.2" + }, + { + "found": "getattr(expr, \"alias\", None)", + "path": "src/rhosocial/activerecord/backend/impl/clickhouse/mixins/json.py", + "rule": "ED-11.2" + }, + { + "found": "getattr(expr, \"alias\", None)", + "path": "src/rhosocial/activerecord/backend/impl/clickhouse/mixins/json.py", + "rule": "ED-11.2" + }, + { + "found": "getattr(expr, \"pairs\", [])", + "path": "src/rhosocial/activerecord/backend/impl/clickhouse/mixins/json.py", + "rule": "ED-11.2" + }, + { + "found": "getattr(expr, \"alias\", None)", + "path": "src/rhosocial/activerecord/backend/impl/clickhouse/mixins/json.py", + "rule": "ED-11.2" + }, + { + "found": "getattr(expr, \"alias\", None)", + "path": "src/rhosocial/activerecord/backend/impl/clickhouse/mixins/json.py", + "rule": "ED-11.2" + }, + { + "found": "getattr(expr, \"values\", [])", + "path": "src/rhosocial/activerecord/backend/impl/clickhouse/mixins/json.py", + "rule": "ED-11.2" + }, + { + "found": "getattr(expr, \"alias\", None)", + "path": "src/rhosocial/activerecord/backend/impl/clickhouse/mixins/json.py", + "rule": "ED-11.2" + }, + { + "found": "getattr(expr, \"path\", None)", + "path": "src/rhosocial/activerecord/backend/impl/clickhouse/mixins/json.py", + "rule": "ED-11.2" + }, + { + "found": "getattr(expr, \"alias\", None)", + "path": "src/rhosocial/activerecord/backend/impl/clickhouse/mixins/json.py", + "rule": "ED-11.2" + }, + { + "found": "getattr(expr, \"alias\", None)", + "path": "src/rhosocial/activerecord/backend/impl/clickhouse/mixins/json.py", + "rule": "ED-11.2" + }, + { + "found": "getattr(expr, \"alias\", None)", + "path": "src/rhosocial/activerecord/backend/impl/clickhouse/mixins/json.py", + "rule": "ED-11.2" + }, + { + "found": "getattr(expr, \"alias\", None)", + "path": "src/rhosocial/activerecord/backend/impl/clickhouse/mixins/json.py", + "rule": "ED-11.2" + }, + { + "found": "getattr(expr, \"alias\", None)", + "path": "src/rhosocial/activerecord/backend/impl/clickhouse/mixins/json.py", + "rule": "ED-11.2" + }, + { + "found": "getattr(expr, \"all\", False)", + "path": "src/rhosocial/activerecord/backend/impl/clickhouse/mixins/json.py", + "rule": "ED-11.2" + }, + { + "found": "getattr(expr, \"path\", None)", + "path": "src/rhosocial/activerecord/backend/impl/clickhouse/mixins/json.py", + "rule": "ED-11.2" + }, + { + "found": "getattr(expr, \"alias\", None)", + "path": "src/rhosocial/activerecord/backend/impl/clickhouse/mixins/json.py", + "rule": "ED-11.2" + }, + { + "found": "getattr(expr, \"view\", None)", + "path": "src/rhosocial/activerecord/backend/impl/clickhouse/mixins/materialized_view.py", + "rule": "ED-11.2" + }, + { + "found": "getattr(expr, 'view', None)", + "path": "src/rhosocial/activerecord/backend/impl/clickhouse/mixins/materialized_view.py", + "rule": "ED-11.2" + }, + { + "found": "getattr(expr, \"to_table\", None)", + "path": "src/rhosocial/activerecord/backend/impl/clickhouse/mixins/materialized_view.py", + "rule": "ED-11.2" + }, + { + "found": "getattr(expr, \"engine\", None)", + "path": "src/rhosocial/activerecord/backend/impl/clickhouse/mixins/materialized_view.py", + "rule": "ED-11.2" + }, + { + "found": "getattr(expr, \"or_replace\", False)", + "path": "src/rhosocial/activerecord/backend/impl/clickhouse/mixins/materialized_view.py", + "rule": "ED-11.2" + }, + { + "found": "getattr(expr, \"if_not_exists\", False)", + "path": "src/rhosocial/activerecord/backend/impl/clickhouse/mixins/materialized_view.py", + "rule": "ED-11.2" + }, + { + "found": "getattr(expr, \"on_cluster\", None)", + "path": "src/rhosocial/activerecord/backend/impl/clickhouse/mixins/materialized_view.py", + "rule": "ED-11.2" + }, + { + "found": "getattr(expr, \"to_columns\", None)", + "path": "src/rhosocial/activerecord/backend/impl/clickhouse/mixins/materialized_view.py", + "rule": "ED-11.2" + }, + { + "found": "getattr(expr, \"engine\", None)", + "path": "src/rhosocial/activerecord/backend/impl/clickhouse/mixins/materialized_view.py", + "rule": "ED-11.2" + }, + { + "found": "getattr(expr, \"populate\", False)", + "path": "src/rhosocial/activerecord/backend/impl/clickhouse/mixins/materialized_view.py", + "rule": "ED-11.2" + }, + { + "found": "getattr(expr, \"refresh\", None)", + "path": "src/rhosocial/activerecord/backend/impl/clickhouse/mixins/materialized_view.py", + "rule": "ED-11.2" + }, + { + "found": "getattr(expr, \"empty\", False)", + "path": "src/rhosocial/activerecord/backend/impl/clickhouse/mixins/materialized_view.py", + "rule": "ED-11.2" + }, + { + "found": "getattr(expr, \"comment\", None)", + "path": "src/rhosocial/activerecord/backend/impl/clickhouse/mixins/materialized_view.py", + "rule": "ED-11.2" + }, + { + "found": "getattr(expr, \"view\", None)", + "path": "src/rhosocial/activerecord/backend/impl/clickhouse/mixins/materialized_view.py", + "rule": "ED-11.2" + }, + { + "found": "getattr(expr, \"cascade\", False)", + "path": "src/rhosocial/activerecord/backend/impl/clickhouse/mixins/materialized_view.py", + "rule": "ED-11.2" + }, + { + "found": "getattr(expr, \"restrict\", False)", + "path": "src/rhosocial/activerecord/backend/impl/clickhouse/mixins/materialized_view.py", + "rule": "ED-11.2" + }, + { + "found": "getattr(expr, \"if_exists\", False)", + "path": "src/rhosocial/activerecord/backend/impl/clickhouse/mixins/materialized_view.py", + "rule": "ED-11.2" + }, + { + "found": "getattr(expr, \"view\", None)", + "path": "src/rhosocial/activerecord/backend/impl/clickhouse/mixins/materialized_view.py", + "rule": "ED-11.2" + }, + { + "found": "getattr(expr, \"concurrent\", False)", + "path": "src/rhosocial/activerecord/backend/impl/clickhouse/mixins/materialized_view.py", + "rule": "ED-11.2" + }, + { + "found": "getattr(expr, \"with_data\", False)", + "path": "src/rhosocial/activerecord/backend/impl/clickhouse/mixins/materialized_view.py", + "rule": "ED-11.2" + }, + { + "found": "getattr(expr, \"no_data\", False)", + "path": "src/rhosocial/activerecord/backend/impl/clickhouse/mixins/materialized_view.py", + "rule": "ED-11.2" + }, + { + "found": "getattr(expr, \"wait\", False)", + "path": "src/rhosocial/activerecord/backend/impl/clickhouse/mixins/materialized_view.py", + "rule": "ED-11.2" + }, + { + "found": "getattr(expr, \"view\", None)", + "path": "src/rhosocial/activerecord/backend/impl/clickhouse/mixins/materialized_view.py", + "rule": "ED-11.2" + }, + { + "found": "getattr(getattr(expr, \"schedule\", None), \"depends_on\", ())", + "path": "src/rhosocial/activerecord/backend/impl/clickhouse/mixins/materialized_view.py", + "rule": "ED-11.2" + }, + { + "found": "getattr(expr, \"schedule\", None)", + "path": "src/rhosocial/activerecord/backend/impl/clickhouse/mixins/materialized_view.py", + "rule": "ED-11.2" + }, + { + "found": "getattr(expr, \"if_exists\", False)", + "path": "src/rhosocial/activerecord/backend/impl/clickhouse/mixins/materialized_view.py", + "rule": "ED-11.2" + } + ], + "format": 1 +} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 2e505b7..da4e5e4 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -66,8 +66,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 ca40701..2a016dd 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/query_connection.py b/tests/providers/query_connection.py index 7a5f050..64dcafd 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_clickhouse_test/feature/backend/ddl/test_ddl_source_mixin.py b/tests/rhosocial/activerecord_clickhouse_test/feature/backend/ddl/test_ddl_source_mixin.py index 4c3a92c..a193b31 100644 --- a/tests/rhosocial/activerecord_clickhouse_test/feature/backend/ddl/test_ddl_source_mixin.py +++ b/tests/rhosocial/activerecord_clickhouse_test/feature/backend/ddl/test_ddl_source_mixin.py @@ -199,9 +199,17 @@ class DeclarationModel( TableDeclarationOverrides, ActiveRecord, ): - __table_name__ = "ddl_source_declarations" - __schema_name__ = "analytics" - __primary_key__ = "record_id" + @classmethod + def table_name(cls): + return "ddl_source_declarations" + + @classmethod + def schema_name(cls): + return "analytics" + + @classmethod + def primary_key(cls): + return "record_id" id: Annotated[int, UseColumn("record_id")] value: Annotated[ @@ -230,9 +238,17 @@ class AsyncDeclarationModel( TableDeclarationOverrides, AsyncActiveRecord, ): - __table_name__ = "ddl_source_declarations_async" - __schema_name__ = "analytics" - __primary_key__ = "record_id" + @classmethod + def table_name(cls): + return "ddl_source_declarations_async" + + @classmethod + def schema_name(cls): + return "analytics" + + @classmethod + def primary_key(cls): + return "record_id" id: Annotated[int, UseColumn("record_id")] value: Annotated[ @@ -257,14 +273,18 @@ class AsyncDeclarationModel( class PlainModel(ActiveRecord): - __table_name__ = "ddl_source_plain" + @classmethod + def table_name(cls): + return "ddl_source_plain" id: int value: Optional[str] = None class AsyncPlainModel(AsyncActiveRecord): - __table_name__ = "ddl_source_plain_async" + @classmethod + def table_name(cls): + return "ddl_source_plain_async" id: int value: Optional[str] = None @@ -275,8 +295,13 @@ class CompositeModel( TableDeclarationOverrides, ActiveRecord, ): - __table_name__ = "ddl_source_composite" - __primary_key__ = ("tenant_id", "order_id") + @classmethod + def table_name(cls): + return "ddl_source_composite" + + @classmethod + def primary_key(cls): + return ("tenant_id", "order_id") tenant_ref: Annotated[int, UseColumn("tenant_id")] order_ref: Annotated[int, UseColumn("order_id")] @@ -290,8 +315,13 @@ class AsyncCompositeModel( TableDeclarationOverrides, AsyncActiveRecord, ): - __table_name__ = "ddl_source_composite_async" - __primary_key__ = ("tenant_id", "order_id") + @classmethod + def table_name(cls): + return "ddl_source_composite_async" + + @classmethod + def primary_key(cls): + return ("tenant_id", "order_id") tenant_ref: Annotated[int, UseColumn("tenant_id")] order_ref: Annotated[int, UseColumn("order_id")] diff --git a/tests/rhosocial/activerecord_clickhouse_test/feature/basic/fields/test_derived_field.py b/tests/rhosocial/activerecord_clickhouse_test/feature/basic/fields/test_derived_field.py index 9a14978..ca0a1d0 100644 --- a/tests/rhosocial/activerecord_clickhouse_test/feature/basic/fields/test_derived_field.py +++ b/tests/rhosocial/activerecord_clickhouse_test/feature/basic/fields/test_derived_field.py @@ -330,7 +330,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( @@ -342,7 +345,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_clickhouse_test/feature/basic/fields/test_derived_field_async.py b/tests/rhosocial/activerecord_clickhouse_test/feature/basic/fields/test_derived_field_async.py index a068eb0..8568cdc 100644 --- a/tests/rhosocial/activerecord_clickhouse_test/feature/basic/fields/test_derived_field_async.py +++ b/tests/rhosocial/activerecord_clickhouse_test/feature/basic/fields/test_derived_field_async.py @@ -330,7 +330,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( @@ -342,7 +345,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_clickhouse_test/feature/basic/fixtures/models.py b/tests/rhosocial/activerecord_clickhouse_test/feature/basic/fixtures/models.py index 74434f6..c9fac2b 100644 --- a/tests/rhosocial/activerecord_clickhouse_test/feature/basic/fixtures/models.py +++ b/tests/rhosocial/activerecord_clickhouse_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 @@ -790,7 +900,9 @@ class Product(ActiveRecord): class AsyncProduct(AsyncActiveRecord): - __table_name__ = "product" + @classmethod + def table_name(cls): + return "product" id: Optional[int] = None name: str @@ -810,7 +922,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 @@ -829,7 +943,9 @@ class ProductFormA(ActiveRecord): class AsyncProductFormA(AsyncActiveRecord): - __table_name__ = "product" + @classmethod + def table_name(cls): + return "product" id: Optional[int] = None name: str @@ -863,7 +979,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 @@ -881,7 +999,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 @@ -900,7 +1020,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 @@ -919,7 +1041,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_clickhouse_test/feature/basic/fixtures/models_py310.py b/tests/rhosocial/activerecord_clickhouse_test/feature/basic/fixtures/models_py310.py index 3a7b604..6768e14 100644 --- a/tests/rhosocial/activerecord_clickhouse_test/feature/basic/fixtures/models_py310.py +++ b/tests/rhosocial/activerecord_clickhouse_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_clickhouse_test/feature/basic/fixtures/models_py311.py b/tests/rhosocial/activerecord_clickhouse_test/feature/basic/fixtures/models_py311.py index 5a6f600..a2c1e09 100644 --- a/tests/rhosocial/activerecord_clickhouse_test/feature/basic/fixtures/models_py311.py +++ b/tests/rhosocial/activerecord_clickhouse_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_clickhouse_test/feature/basic/fixtures/models_py312.py b/tests/rhosocial/activerecord_clickhouse_test/feature/basic/fixtures/models_py312.py index f0f74f5..ec71b7e 100644 --- a/tests/rhosocial/activerecord_clickhouse_test/feature/basic/fixtures/models_py312.py +++ b/tests/rhosocial/activerecord_clickhouse_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_clickhouse_test/feature/events/fixtures/models.py b/tests/rhosocial/activerecord_clickhouse_test/feature/events/fixtures/models.py index 5d7d69f..93c6091 100644 --- a/tests/rhosocial/activerecord_clickhouse_test/feature/events/fixtures/models.py +++ b/tests/rhosocial/activerecord_clickhouse_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_clickhouse_test/feature/events/fixtures/models_py310.py b/tests/rhosocial/activerecord_clickhouse_test/feature/events/fixtures/models_py310.py index 0e9dba0..bd3ee5e 100644 --- a/tests/rhosocial/activerecord_clickhouse_test/feature/events/fixtures/models_py310.py +++ b/tests/rhosocial/activerecord_clickhouse_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_clickhouse_test/feature/events/fixtures/models_py311.py b/tests/rhosocial/activerecord_clickhouse_test/feature/events/fixtures/models_py311.py index f48aa46..786f4f3 100644 --- a/tests/rhosocial/activerecord_clickhouse_test/feature/events/fixtures/models_py311.py +++ b/tests/rhosocial/activerecord_clickhouse_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_clickhouse_test/feature/events/fixtures/models_py312.py b/tests/rhosocial/activerecord_clickhouse_test/feature/events/fixtures/models_py312.py index f4b82d0..9196e1a 100644 --- a/tests/rhosocial/activerecord_clickhouse_test/feature/events/fixtures/models_py312.py +++ b/tests/rhosocial/activerecord_clickhouse_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_clickhouse_test/feature/mixins/fixtures/models.py b/tests/rhosocial/activerecord_clickhouse_test/feature/mixins/fixtures/models.py index 922ffd1..921aa24 100644 --- a/tests/rhosocial/activerecord_clickhouse_test/feature/mixins/fixtures/models.py +++ b/tests/rhosocial/activerecord_clickhouse_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_clickhouse_test/feature/mixins/fixtures/models_py310.py b/tests/rhosocial/activerecord_clickhouse_test/feature/mixins/fixtures/models_py310.py index c587ccc..b7d0778 100644 --- a/tests/rhosocial/activerecord_clickhouse_test/feature/mixins/fixtures/models_py310.py +++ b/tests/rhosocial/activerecord_clickhouse_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_clickhouse_test/feature/mixins/fixtures/models_py311.py b/tests/rhosocial/activerecord_clickhouse_test/feature/mixins/fixtures/models_py311.py index 6a8798c..978afa7 100644 --- a/tests/rhosocial/activerecord_clickhouse_test/feature/mixins/fixtures/models_py311.py +++ b/tests/rhosocial/activerecord_clickhouse_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_clickhouse_test/feature/mixins/fixtures/models_py312.py b/tests/rhosocial/activerecord_clickhouse_test/feature/mixins/fixtures/models_py312.py index 36ccbe3..176fabe 100644 --- a/tests/rhosocial/activerecord_clickhouse_test/feature/mixins/fixtures/models_py312.py +++ b/tests/rhosocial/activerecord_clickhouse_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_clickhouse_test/feature/relation/fixtures/models.py b/tests/rhosocial/activerecord_clickhouse_test/feature/relation/fixtures/models.py index d975fed..6673931 100644 --- a/tests/rhosocial/activerecord_clickhouse_test/feature/relation/fixtures/models.py +++ b/tests/rhosocial/activerecord_clickhouse_test/feature/relation/fixtures/models.py @@ -16,7 +16,7 @@ from rhosocial.activerecord.backend.expression import Column, Literal from rhosocial.activerecord.backend.expression.operators import ArithmeticOperation 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 @@ -25,7 +25,9 @@ # ── Basic Relation Models ──────────────────────────────── class Employee(ActiveRecord): - __table_name__ = "employees" + @classmethod + def table_name(cls): + return "employees" id: Optional[int] = None username: str @@ -38,7 +40,9 @@ class Employee(ActiveRecord): class Department(ActiveRecord): - __table_name__ = "departments" + @classmethod + def table_name(cls): + return "departments" id: Optional[int] = None name: str @@ -51,7 +55,9 @@ class Department(ActiveRecord): class Author(ActiveRecord): - __table_name__ = "authors" + @classmethod + def table_name(cls): + return "authors" id: Optional[int] = None name: str @@ -67,7 +73,9 @@ class Author(ActiveRecord): class Book(ActiveRecord): - __table_name__ = "books" + @classmethod + def table_name(cls): + return "books" id: Optional[int] = None title: str @@ -84,7 +92,9 @@ class Book(ActiveRecord): class Chapter(ActiveRecord): - __table_name__ = "chapters" + @classmethod + def table_name(cls): + return "chapters" id: Optional[int] = None title: str @@ -97,7 +107,9 @@ class Chapter(ActiveRecord): class Profile(ActiveRecord): - __table_name__ = "profiles" + @classmethod + def table_name(cls): + return "profiles" id: Optional[int] = None bio: str @@ -112,7 +124,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 @@ -143,7 +157,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 @@ -185,7 +201,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 @@ -213,7 +231,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 @@ -240,7 +260,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 @@ -277,7 +299,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 @@ -302,7 +326,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 @@ -318,7 +344,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 @@ -331,7 +359,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 @@ -344,7 +374,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 @@ -360,7 +392,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 @@ -373,7 +407,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_clickhouse_test/feature/relation/fixtures/models_py310.py b/tests/rhosocial/activerecord_clickhouse_test/feature/relation/fixtures/models_py310.py index 20e1016..e91bf2c 100644 --- a/tests/rhosocial/activerecord_clickhouse_test/feature/relation/fixtures/models_py310.py +++ b/tests/rhosocial/activerecord_clickhouse_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_clickhouse_test/feature/relation/fixtures/models_py311.py b/tests/rhosocial/activerecord_clickhouse_test/feature/relation/fixtures/models_py311.py index a6835c3..ea692f3 100644 --- a/tests/rhosocial/activerecord_clickhouse_test/feature/relation/fixtures/models_py311.py +++ b/tests/rhosocial/activerecord_clickhouse_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_clickhouse_test/feature/relation/fixtures/models_py312.py b/tests/rhosocial/activerecord_clickhouse_test/feature/relation/fixtures/models_py312.py index 84ce68c..75a3906 100644 --- a/tests/rhosocial/activerecord_clickhouse_test/feature/relation/fixtures/models_py312.py +++ b/tests/rhosocial/activerecord_clickhouse_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