Weird issues with Dataclass + Declarative + own generic class

See original GitHub issue

Describe the bug

Yesterday I could run my program perfectly 😄

Today, I was trying to create a class that is generic on a parameter, and I started getting weird errors. Trying to figure out what I was doing wrong, I reduced this generic class piece by piece, until basically two columns are left, and I still get weird errors. I double checked and it had all the same members as my original Base Entity, so I don’t see what is wrong tbh

To Reproduce

from sqlalchemy import Integer, String
from sqlalchemy.orm import DeclarativeBase, Mapped, MappedAsDataclass, mapped_column


class SomeBaseClass(DeclarativeBase, MappedAsDataclass):
    pass


class GenericSetting(SomeBaseClass):
    """Represents key value pairs for settings or values"""

    __tablename__ = "x_table_x"

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

    key: Mapped[str] = mapped_column(String, init=True)


config = ""
new_instance: GenericSetting

Error

---------------------------------------------------------------------------
ArgumentError                             Traceback (most recent call last)
c:\DEV\liquidity\generic_test.py in line 12
      [8](file:///c%3A/DEV/liquidity/generic_test.py?line=7) class SomeBaseClass(DeclarativeBase, MappedAsDataclass):
      [9](file:///c%3A/DEV/liquidity/generic_test.py?line=8)     pass
---> [12](file:///c%3A/DEV/liquidity/generic_test.py?line=11) class GenericSetting(SomeBaseClass):
     [13](file:///c%3A/DEV/liquidity/generic_test.py?line=12)     """Represents key value pairs for settings or values"""
     [15](file:///c%3A/DEV/liquidity/generic_test.py?line=14)     __tablename__ = "x_table_x"

File c:\DEV\liquidity\.venv\lib\site-packages\sqlalchemy\orm\decl_api.py:698, in DeclarativeBase.__init_subclass__(cls)
    [696](file:///c%3A/DEV/liquidity/.venv/lib/site-packages/sqlalchemy/orm/decl_api.py?line=695)     _setup_declarative_base(cls)
    [697](file:///c%3A/DEV/liquidity/.venv/lib/site-packages/sqlalchemy/orm/decl_api.py?line=696) else:
--> [698](file:///c%3A/DEV/liquidity/.venv/lib/site-packages/sqlalchemy/orm/decl_api.py?line=697)     _as_declarative(cls._sa_registry, cls, cls.__dict__)

File c:\DEV\liquidity\.venv\lib\site-packages\sqlalchemy\orm\decl_base.py:207, in _as_declarative(registry, cls, dict_)
    [201](file:///c%3A/DEV/liquidity/.venv/lib/site-packages/sqlalchemy/orm/decl_base.py?line=200) def _as_declarative(
    [202](file:///c%3A/DEV/liquidity/.venv/lib/site-packages/sqlalchemy/orm/decl_base.py?line=201)     registry: _RegistryType, cls: Type[Any], dict_: _ClassDict
    [203](file:///c%3A/DEV/liquidity/.venv/lib/site-packages/sqlalchemy/orm/decl_base.py?line=202) ) -> Optional[_MapperConfig]:
    [204](file:///c%3A/DEV/liquidity/.venv/lib/site-packages/sqlalchemy/orm/decl_base.py?line=203) 
    [205](file:///c%3A/DEV/liquidity/.venv/lib/site-packages/sqlalchemy/orm/decl_base.py?line=204)     # declarative scans the class for attributes.  no table or mapper
    [206](file:///c%3A/DEV/liquidity/.venv/lib/site-packages/sqlalchemy/orm/decl_base.py?line=205)     # args passed separately.
--> [207](file:///c%3A/DEV/liquidity/.venv/lib/site-packages/sqlalchemy/orm/decl_base.py?line=206)     return _MapperConfig.setup_mapping(registry, cls, dict_, None, {})

File c:\DEV\liquidity\.venv\lib\site-packages\sqlalchemy\orm\decl_base.py:288, in _MapperConfig.setup_mapping(cls, registry, cls_, dict_, table, mapper_kw)
    [284](file:///c%3A/DEV/liquidity/.venv/lib/site-packages/sqlalchemy/orm/decl_base.py?line=283)     return _DeferredMapperConfig(
    [285](file:///c%3A/DEV/liquidity/.venv/lib/site-packages/sqlalchemy/orm/decl_base.py?line=284)         registry, cls_, dict_, table, mapper_kw
    [286](file:///c%3A/DEV/liquidity/.venv/lib/site-packages/sqlalchemy/orm/decl_base.py?line=285)     )
    [287](file:///c%3A/DEV/liquidity/.venv/lib/site-packages/sqlalchemy/orm/decl_base.py?line=286) else:
--> [288](file:///c%3A/DEV/liquidity/.venv/lib/site-packages/sqlalchemy/orm/decl_base.py?line=287)     return _ClassScanMapperConfig(
    [289](file:///c%3A/DEV/liquidity/.venv/lib/site-packages/sqlalchemy/orm/decl_base.py?line=288)         registry, cls_, dict_, table, mapper_kw
    [290](file:///c%3A/DEV/liquidity/.venv/lib/site-packages/sqlalchemy/orm/decl_base.py?line=289)     )

File c:\DEV\liquidity\.venv\lib\site-packages\sqlalchemy\orm\decl_base.py:523, in _ClassScanMapperConfig.__init__(self, registry, cls_, dict_, table, mapper_kw)
    [518](file:///c%3A/DEV/liquidity/.venv/lib/site-packages/sqlalchemy/orm/decl_base.py?line=517) with mapperlib._CONFIGURE_MUTEX:
    [519](file:///c%3A/DEV/liquidity/.venv/lib/site-packages/sqlalchemy/orm/decl_base.py?line=518)     clsregistry.add_class(
    [520](file:///c%3A/DEV/liquidity/.venv/lib/site-packages/sqlalchemy/orm/decl_base.py?line=519)         self.classname, self.cls, registry._class_registry
    [521](file:///c%3A/DEV/liquidity/.venv/lib/site-packages/sqlalchemy/orm/decl_base.py?line=520)     )
--> [523](file:///c%3A/DEV/liquidity/.venv/lib/site-packages/sqlalchemy/orm/decl_base.py?line=522)     self._extract_mappable_attributes()
    [525](file:///c%3A/DEV/liquidity/.venv/lib/site-packages/sqlalchemy/orm/decl_base.py?line=524)     self._extract_declared_columns()
    [527](file:///c%3A/DEV/liquidity/.venv/lib/site-packages/sqlalchemy/orm/decl_base.py?line=526)     self._setup_table(table)

File c:\DEV\liquidity\.venv\lib\site-packages\sqlalchemy\orm\decl_base.py:1299, in _ClassScanMapperConfig._extract_mappable_attributes(self)
   [1289](file:///c%3A/DEV/liquidity/.venv/lib/site-packages/sqlalchemy/orm/decl_base.py?line=1288)             argnames = ["init", "default_factory", "repr"]
   [1291](file:///c%3A/DEV/liquidity/.venv/lib/site-packages/sqlalchemy/orm/decl_base.py?line=1290)         args = {
   [1292](file:///c%3A/DEV/liquidity/.venv/lib/site-packages/sqlalchemy/orm/decl_base.py?line=1291)             a
   [1293](file:///c%3A/DEV/liquidity/.venv/lib/site-packages/sqlalchemy/orm/decl_base.py?line=1292)             for a in argnames
   (...)
   [1297](file:///c%3A/DEV/liquidity/.venv/lib/site-packages/sqlalchemy/orm/decl_base.py?line=1296)             is not _NoArg.NO_ARG
   [1298](file:///c%3A/DEV/liquidity/.venv/lib/site-packages/sqlalchemy/orm/decl_base.py?line=1297)         }
-> [1299](file:///c%3A/DEV/liquidity/.venv/lib/site-packages/sqlalchemy/orm/decl_base.py?line=1298)         raise exc.ArgumentError(
   [1300](file:///c%3A/DEV/liquidity/.venv/lib/site-packages/sqlalchemy/orm/decl_base.py?line=1299)             f"Attribute '{k}' on class {cls} includes dataclasses "
   [1301](file:///c%3A/DEV/liquidity/.venv/lib/site-packages/sqlalchemy/orm/decl_base.py?line=1300)             f"argument(s): "
   [1302](file:///c%3A/DEV/liquidity/.venv/lib/site-packages/sqlalchemy/orm/decl_base.py?line=1301)             f"{', '.join(sorted(repr(a) for a in args))} but "
   [1303](file:///c%3A/DEV/liquidity/.venv/lib/site-packages/sqlalchemy/orm/decl_base.py?line=1302)             f"class does not specify "
   [1304](file:///c%3A/DEV/liquidity/.venv/lib/site-packages/sqlalchemy/orm/decl_base.py?line=1303)             "SQLAlchemy native dataclass configuration."
   [1305](file:///c%3A/DEV/liquidity/.venv/lib/site-packages/sqlalchemy/orm/decl_base.py?line=1304)         )
   [1307](file:///c%3A/DEV/liquidity/.venv/lib/site-packages/sqlalchemy/orm/decl_base.py?line=1306) our_stuff[k] = value

ArgumentError: Attribute 'id' on class <class '__main__.GenericSetting'> includes dataclasses argument(s): 'init' but class does not specify SQLAlchemy native dataclass configuration.

Versions

  • OS:
  • Python: 3.10.8
  • SQLAlchemy: latest beta
  • Database:
  • DBAPI (eg: psycopg, cx_oracle, mysqlclient):

Additional context

No response

Issue Analytics

  • State:closed
  • Created a year ago
  • Comments:19 (12 by maintainers)

github_iconTop GitHub Comments

1reaction
zzzeekcommented, Oct 18, 2022

oh you are type qualifying it

1reaction
zzzeekcommented, Oct 18, 2022

this is good beta tester stuff, thanks

Read more comments on GitHub >

github_iconTop Results From Across the Web

Template / Generic user-defined classes in python weird ...
Closed last year. When I write the following code, mypy issues an error (like it should): from typing import TypeVar, Generic ...
Read more >
typescript-cheatsheet - GitHub Pages
A set of TypeScript related notes used for quick reference. The cheatsheet contains references to types, classes, decorators, and many other TypeScript ...
Read more >
I use Attrs instead of Pydantic - Hacker News
Dacite and marshmallow-dataclasses don't support generics well either, with some issues around Union types. They do work well for simple python ...
Read more >
Improving Python's SimpleNamespace - LWN.net
Python's SimpleNamespace class provides an easy way for a programmer to create an object to store values as attributes without creating their own...
Read more >
Scala for Generic Programmers
Comparing Haskell and Scala Support for Generic Programming. BRUNO C. D. S. OLIVEIRA ... the explicit and implicit cases is awkward.
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