Skip to content

Bug: Unable to create model from dict with nested dicts #556

@funkindy

Description

@funkindy

Description

I provide model with relationships as nested dicts like this:

class Parent(Base):
    __tablename__ = "parent"

    id = Column(Integer, primary_key=True)
    name = Column(String)

    nested = relationship("Nested", back_populates="parent", cascade="all, delete-orphan")


class Nested(Base):
    __tablename__ = "nested"

    id = Column(Integer, primary_key=True)
    name = Column(String)

    parent_id = Column(Integer, ForeignKey("parent.id"))
    parent = relationship("Parent", back_populates="nested")

raw_data = {"name": "parent", "nested": [{"name": "related1"}, {"name": "related2"}] 

Now i want to create it with RepositoryService. Before 1.6.0 it worked but ignored related models.

Now after 1.6.0 it breaks because nested models are also dicts, SQLAlchemy raises AttributeError: 'dict' object has no attribute '_sa_instance_state'. I think this is happening because model_to_dict dosent do much introspection and doesnt apply on related dicts/lists.

URL to code causing the issue

No response

MCVE

Steps to reproduce

Screenshots

No response

Logs

.venv/lib/python3.12/site-packages/advanced_alchemy/service/_async.py:653: in create
    data = await self.to_model(data, "create")
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.venv/lib/python3.12/site-packages/advanced_alchemy/service/_async.py:446: in to_model
    return model_from_dict(model=self.model_type, **data)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.venv/lib/python3.12/site-packages/advanced_alchemy/repository/_util.py:105: in model_from_dict
    return model(**data)
           ^^^^^^^^^^^^^
<string>:4: in __init__
    ???
.venv/lib/python3.12/site-packages/sqlalchemy/orm/state.py:571: in _initialize_instance
    with util.safe_reraise():
.venv/lib/python3.12/site-packages/sqlalchemy/util/langhelpers.py:224: in __exit__
    raise exc_value.with_traceback(exc_tb)
.venv/lib/python3.12/site-packages/sqlalchemy/orm/state.py:569: in _initialize_instance
    manager.original_init(*mixed[1:], **kwargs)
.venv/lib/python3.12/site-packages/sqlalchemy/orm/decl_base.py:2182: in _declarative_constructor
    setattr(self, k, kwargs[k])
.venv/lib/python3.12/site-packages/sqlalchemy/orm/attributes.py:540: in __set__
    self.impl.set(
.venv/lib/python3.12/site-packages/sqlalchemy/orm/attributes.py:1995: in set
    collections.bulk_replace(
.venv/lib/python3.12/site-packages/sqlalchemy/orm/collections.py:811: in bulk_replace
    appender(member, _sa_initiator=initiator)
.venv/lib/python3.12/site-packages/sqlalchemy/orm/collections.py:1138: in append
    item = __set(self, item, _sa_initiator, NO_KEY)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.venv/lib/python3.12/site-packages/sqlalchemy/orm/collections.py:1103: in __set
    item = executor.fire_append_event(item, _sa_initiator, key=key)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.venv/lib/python3.12/site-packages/sqlalchemy/orm/collections.py:695: in fire_append_event
    return self.attr.fire_append_event(
.venv/lib/python3.12/site-packages/sqlalchemy/orm/attributes.py:1762: in fire_append_event
    value = fn(state, value, initiator or self._append_token, key=key)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

state = <sqlalchemy.orm.state.InstanceState object at 0x123704290>
child = DICT HERE
initiator = <sqlalchemy.orm.attributes.AttributeEventToken object at 0x127aa68c0>
kw = {'key': <EventConstants.NO_KEY: 4>}

    def emit_backref_from_collection_append_event(
        state, child, initiator, **kw
    ):
        if child is None:
            return
    
>       child_state, child_dict = instance_state(child), instance_dict(child)
                                  ^^^^^^^^^^^^^^^^^^^^^
E       AttributeError: 'dict' object has no attribute '_sa_instance_state'

.venv/lib/python3.12/site-packages/sqlalchemy/orm/attributes.py:2209: AttributeError

Package Version

1.6.0+

Platform

  • Linux
  • Mac
  • Windows
  • Other (Please specify in the description above)

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions