Skip to content

🐛 Move __tablename__ default from @declared_attr to metaclass#1821

Open
estarfoo wants to merge 1 commit intofastapi:mainfrom
estarfoo:feat/tablename-property
Open

🐛 Move __tablename__ default from @declared_attr to metaclass#1821
estarfoo wants to merge 1 commit intofastapi:mainfrom
estarfoo:feat/tablename-property

Conversation

@estarfoo
Copy link

Move the default __tablename__ from a @declared_attr method to SQLModelMetaclass.__new__, where it is set in the class dict before class creation, alongside the existing setup.

This resolves the type-level contradiction between the ClassVar[str | Callable] declaration and the @declared_attr descriptor, letting __tablename__ = "my_table" work without # type: ignore for pyright.

Tests added for default name, explicit override, inheritance, and non-table models.

Fixes #98.

This is split out from #1820, dropping those changes which would be resolved by #1345 or #1806.

The `SQLModel` base class declared `__tablename__` both as a `ClassVar`
and as a `@declared_attr` method.  Some type checkers (pyright) see the
descriptor type from `@declared_attr`, so setting
`__tablename__ = "my_table"` in a subclass is rejected as a type
mismatch, even though it works at runtime.

Replace the `@declared_attr` method with a default set in
`SQLModelMetaclass.__new__` via `dict_used`, before class creation.

Fixes fastapi#98.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@svlandeg svlandeg added the bug Something isn't working label Mar 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Pyright cannot recognize the type of SQLModel.__tablename__

3 participants