Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

structure doesn't recognise init=False on SQLAlchemy's declarative base integration #428

Closed
tjader opened this issue Sep 21, 2023 · 3 comments

Comments

@tjader
Copy link

tjader commented Sep 21, 2023

  • cattrs version: 23.1
  • Python version: 3.11
  • Operating System: Ubuntu 22.04 LTS

Description

SQLAlchemy 2.0 has a new integration with dataclasses (and to some extent attrs). It somewhat works with cattrs as well. However, cattrs doesn't detect the init=False flag on the mapped columns (i.e dataclass fields).

What I Did

Using the example in sqlalchemy's documentation (https://docs.sqlalchemy.org/en/20/orm/dataclasses.html#declarative-dataclass-mapping), you can try running structure on some data. This works if there is no init=False column

from sqlalchemy.orm import DeclarativeBase
from sqlalchemy.orm import Mapped
from sqlalchemy.orm import mapped_column
from sqlalchemy.orm import MappedAsDataclass
from cattrs import structure, unstructure

class Base(MappedAsDataclass, DeclarativeBase):
    """subclasses will be converted to dataclasses"""


class User1(Base):
    __tablename__ = "user1"

    id: Mapped[int] = mapped_column(primary_key=True)
    name: Mapped[str]

class User2(Base):
    __tablename__ = "user2"

    id: Mapped[int] = mapped_column(init=False, primary_key=True)
    name: Mapped[str]

a = structure({'id':1, 'name': 'abc'}, User1)

But fails, if we try to structure a class with a init=False field

structure({'name': 'abc'}, User2)
  + Exception Group Traceback (most recent call last):
  |   File "/home/mats/miniconda3/envs/bfbet/lib/python3.11/site-packages/IPython/core/interactiveshell.py", line 3508, in run_code
  |     exec(code_obj, self.user_global_ns, self.user_ns)
  |   File "<ipython-input-2-27bab276a8a2>", line 1, in <module>
  |     structure({'name': 'abc'}, User2)
  |   File "/home/mats/miniconda3/envs/bfbet/lib/python3.11/site-packages/cattrs/converters.py", line 334, in structure
  |     return self._structure_func.dispatch(cl)(obj, cl)
  |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |   File "<cattrs generated structure __main__.User2>", line 14, in structure_User2
  |     if errors: raise __c_cve('While structuring ' + 'User2', errors, __cl)
  |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  | cattrs.errors.ClassValidationError: While structuring User2 (1 sub-exception)
  +-+---------------- 1 ----------------
    | Traceback (most recent call last):
    |   File "<cattrs generated structure __main__.User2>", line 5, in structure_User2
    |     res['id'] = __c_structure_id(o['id'])
    |                                   ~^^^^^^
    | KeyError: 'id'
    | Structuring class User2 @ attribute id
    +------------------------------------
@tjader
Copy link
Author

tjader commented Sep 21, 2023

I just found this closed (but as of now unreleased) issue. #40

@Tinche
Copy link
Member

Tinche commented Sep 21, 2023

Yeah, can you give it a test with main? The next release is very close.

@tjader
Copy link
Author

tjader commented Sep 21, 2023

Thanks - The issue has been solved in main already. Looking forward to the next release.

@tjader tjader closed this as completed Sep 21, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants