question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

update the allow_unmapped error message to be less confusing with dataclasses; consider adding InitVar to whitelist

See original GitHub issue

Describe the use case

Dataclasses allow for Init-only variables by type hinting using InitVar. This allows for adding __init__ arguments, that are not stored in the dataclass. These are typically used by __post_init__ methods.

Sqlalchemy should should allow one to use InitVar by simply ignore these fields, as it does with ClassVar

It would be useful where one would want to simplify initialization of sqlalchemy dataclass orm objects.

Databases / Backends / Drivers targeted

All

Example Use

@dataclass
class Identity:
    display_name: str
    user_id: str
    principals: List[str] = field(default_factory=list)

@reg.mapped_as_dataclass()
class AuditLog:
    __tablename__ = "audit_log"
    alid: Mapped[int] = mapped_column(primary_key=True, init=False)
    action: Mapped[str] = mapped_column()
    timestamp: Mapped[datetime] = mapped_column(default_factory=datetime.now)
    data: Mapped[Dict] = mapped_column(JSONB, default_factory=dict)

    user_id: Mapped[str] = mapped_column(default_factory=None)
    identity: InitVar[Identity] = field(default=None)

    def __post_init__(self, identity: Identity):
        if identity:
            self.user_id = identity.user_id

identity = Identity(display_name="John Smith", user_id="john")
audit_log = AuditLog(identity=identity, action="delete_object")

Additional context

No response

Issue Analytics

  • State:closed
  • Created 9 months ago
  • Comments:11 (8 by maintainers)

github_iconTop GitHub Comments

1reaction
zzzeekcommented, Dec 13, 2022

hey thanks for that.

this is still expected behavior, though i guess the ask is that “InitVar” be added to the whitelist. Take a look at what the message says, and from there we can solve the problem by adding __allow_unmapped__ as mentioned:

@reg.mapped_as_dataclass()
class AuditLog:
    __allow_unmapped__ = True
    __tablename__ = "audit_log"
    alid: Mapped[int] = mapped_column(primary_key=True, init=False)
    action: Mapped[str] = mapped_column()
    timestamp: Mapped[datetime] = mapped_column(default_factory=datetime.now)

    user_id: Mapped[Optional[str]] = mapped_column(default=None)
    identity: InitVar[Optional[Identity]] = None

    def __post_init__(self, identity: Optional[Identity]):
        if identity:
            self.user_id = identity.user_id

This is tested as a use case for dataclasses at https://github.com/sqlalchemy/sqlalchemy/blob/e0eea374c2df82f879d69b99ba2230c743bbae27/test/orm/declarative/test_dc_transforms.py#L387 . the goal is to prevent attributes that are ambiguous for their intent to pass silently.

0reactions
sqla-testercommented, Dec 18, 2022

Mike Bayer has proposed a fix for this issue in the main branch:

remove allow_unmapped requirement from dataclasses https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/4312

Read more comments on GitHub >

github_iconTop Results From Across the Web

Error on instance property and init-only variable with the same ...
This is a problem with mypy's dataclasses plugin, I suppose. However, as mypy would have already processed the class (I think?) before the ......
Read more >
dataclasses — Data Classes — Python 3.11.1 documentation
The decorator returns the same class that it is called on; no new class is created. If dataclass() is used just as a...
Read more >
Cannot call replace() on a dataclass with InitVar - Stack Overflow
Having InitVar s in your dataclass means that you can't call the constructor without explicitly passing the InitVar again.
Read more >
Everything you need to know about dataclasses - rmcomplexity
Updating an object instance by replacing the entire object. Adding class attributes; Inheritance in data classes; Hash-able object; A use case ...
Read more >
Data Classes in Python 3.7+ (Guide)
In this tutorial, you will learn exactly which conveniences data classes provide. In addition to nice representations and comparisons, you'll see: How to...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found