typing related issues to custom record class. #1258
-
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 4 replies
-
|
The issue is that The cleaner approach is to use a Option 1 — TypedDict (recommended for query results) from typing import TypedDict
import asyncpg
class UserRecord(TypedDict):
id: int
username: str
password: str
# Cast the result
row = await conn.fetchrow("SELECT id, username, password FROM users WHERE id = $1", user_id)
user: UserRecord = dict(row) # type: ignore[assignment]
print(user["username"]) # fully typedOption 2 — Keep subclassing but suppress the Pyright error Pyright does not support from typing import Any
import asyncpg
class User(asyncpg.Record):
id: int # declare directly
username: str
password: str
def __getattr__(self, name: str) -> Any:
return self[name]Declaring them outside Option 3 — Use Asyncpg supports passing a custom from typing import Protocol
class UserLike(Protocol):
@property
def id(self) -> int: ...
@property
def username(self) -> str: ...For most cases, Option 1 (TypedDict) is the least friction and works well with type checkers. |
Beta Was this translation helpful? Give feedback.
-
|
I'm the author of Option 1: use dict-like access and trick the type checker to think your class is both # types.py:
from typing import TYPE_CHECKING, TypedDict
import asyncpg
if TYPE_CHECKING:
class Record(asyncpg.Record, TypedDict): ... # pyright: ignore
else:
Record = asyncpg.Record
# another_module.py:
from .types import Record
class MyRecord(Record):
id: int
username: str
password: str
async def do_something() -> None:
row = await conn.fetchrow("SELECT id, username, password FROM users WHERE id = $1", user_id, record_class=MyRecord)
assert_type(row['id'], int)Option 2: use dotted notation and trick the type checker with # types.py:
from typing import TYPE_CHECKING, Any
import asyncpg
if TYPE_CHECKING:
@dataclass_transform(eq_default=True, order_default=True)
class Record(asyncpg.Record): ...
else:
class Record(asyncpg.Record):
def __getattr__(self, name: str) -> Any:
return self[name]
# another_module.py:
from .types import Record
class MyRecord(Record):
id: int
username: str
password: str
async def do_something() -> None:
row = await conn.fetchrow("SELECT id, username, password FROM users WHERE id = $1", user_id, record_class=MyRecord)
assert_type(row.id, int)It sounds like you did something similar to option 2, but I would recommend using the |
Beta Was this translation helpful? Give feedback.

I'm the author of
asyncpg-stubs. Your best bet will be to do one of the following:Option 1: use dict-like access and trick the type checker to think your class is both
TypedDictandasyncpg.Record