Skip to content

AttributeError while creating object with nested data/modelΒ #293

@kido5217

Description

@kido5217

First Check

  • I added a very descriptive title to this issue.
  • I used the GitHub search to find a similar issue and didn't find it.
  • I searched the SQLModel documentation, with the integrated search.
  • I already searched in Google "How to X in SQLModel" and didn't find any information.
  • I already read and followed all the tutorial in the docs and didn't find an answer.
  • I already checked if it is not related to SQLModel but to Pydantic.
  • I already checked if it is not related to SQLModel but to SQLAlchemy.

Commit to Help

  • I commit to help with one of those options πŸ‘†

Example Code

from typing import List, Optional

from sqlmodel import Field, Relationship, Session, SQLModel, create_engine

device_data = {
    "name": "Router",
    "interfaces": [
        {
            "name": "eth0",
            "description": "Ethernet 0",
        },
        {
            "name": "eth1",
            "description": "Ethernet 1",
        },
    ],
}


class Device(SQLModel, table=True):
    id: Optional[int] = Field(default=None, primary_key=True)

    name: str = Field(index=True)

    interfaces: List["Interface"] = Relationship(back_populates="device")


class Interface(SQLModel, table=True):
    id: Optional[int] = Field(default=None, primary_key=True)

    name: str = Field(index=True)
    description: str

    device_id: Optional[int] = Field(default=None, foreign_key="device.id")
    device: Optional[Device] = Relationship(back_populates="interfaces")


def main():

    engine = create_engine("sqlite:///database.db", echo=True)
    SQLModel.metadata.create_all(engine)

    with Session(engine) as session:
        device = Device.parse_obj(device_data)
        session.add(device)
        session.commit()


if __name__ == "__main__":
    main()

Description

I'm trying to use nested models to parse structured data and store it in DB.
In test program, example dataset is created in variable device_data

After creating test data and Device and Interface models with One-to-Many relationship, I'm trying to create device object: device = Device.parse_obj(device_data), but I'm getting exception: AttributeError: 'dict' object has no attribute '_sa_instance_state'

Operating System

Linux

Operating System Details

No response

SQLModel Version

0.0.6

Python Version

Python 3.10.4

Additional Context

Full output:

2022-04-03 01:17:34,890 INFO sqlalchemy.engine.Engine BEGIN (implicit)
2022-04-03 01:17:34,890 INFO sqlalchemy.engine.Engine PRAGMA main.table_info("device")
2022-04-03 01:17:34,890 INFO sqlalchemy.engine.Engine [raw sql] ()
2022-04-03 01:17:34,892 INFO sqlalchemy.engine.Engine PRAGMA temp.table_info("device")
2022-04-03 01:17:34,892 INFO sqlalchemy.engine.Engine [raw sql] ()
2022-04-03 01:17:34,892 INFO sqlalchemy.engine.Engine PRAGMA main.table_info("interface")
2022-04-03 01:17:34,892 INFO sqlalchemy.engine.Engine [raw sql] ()
2022-04-03 01:17:34,892 INFO sqlalchemy.engine.Engine PRAGMA temp.table_info("interface")
2022-04-03 01:17:34,893 INFO sqlalchemy.engine.Engine [raw sql] ()
2022-04-03 01:17:34,893 INFO sqlalchemy.engine.Engine 
CREATE TABLE device (
        id INTEGER, 
        name VARCHAR NOT NULL, 
        PRIMARY KEY (id)
)


2022-04-03 01:17:34,893 INFO sqlalchemy.engine.Engine [no key 0.00006s] ()
2022-04-03 01:17:34,901 INFO sqlalchemy.engine.Engine CREATE INDEX ix_device_name ON device (name)
2022-04-03 01:17:34,901 INFO sqlalchemy.engine.Engine [no key 0.00013s] ()
2022-04-03 01:17:34,912 INFO sqlalchemy.engine.Engine 
CREATE TABLE interface (
        id INTEGER, 
        name VARCHAR NOT NULL, 
        description VARCHAR NOT NULL, 
        device_id INTEGER, 
        PRIMARY KEY (id), 
        FOREIGN KEY(device_id) REFERENCES device (id)
)


2022-04-03 01:17:34,912 INFO sqlalchemy.engine.Engine [no key 0.00020s] ()
2022-04-03 01:17:34,921 INFO sqlalchemy.engine.Engine CREATE INDEX ix_interface_name ON interface (name)
2022-04-03 01:17:34,921 INFO sqlalchemy.engine.Engine [no key 0.00014s] ()
2022-04-03 01:17:34,930 INFO sqlalchemy.engine.Engine COMMIT
Traceback (most recent call last):
  File "/home/kido/projects/test/python/pydser/./pyser.py", line 52, in <module>
    main()
  File "/home/kido/projects/test/python/pydser/./pyser.py", line 46, in main
    device = Device.parse_obj(device_data)
  File "/home/kido/projects/test/python/pydser/.venv/lib/python3.10/site-packages/sqlmodel/main.py", line 578, in parse_obj
    return super().parse_obj(obj)
  File "pydantic/main.py", line 511, in pydantic.main.BaseModel.parse_obj
  File "<string>", line 4, in __init__
  File "/home/kido/projects/test/python/pydser/.venv/lib/python3.10/site-packages/sqlalchemy/orm/state.py", line 479, in _initialize_instance
    with util.safe_reraise():
  File "/home/kido/projects/test/python/pydser/.venv/lib/python3.10/site-packages/sqlalchemy/util/langhelpers.py", line 70, in __exit__
    compat.raise_(
  File "/home/kido/projects/test/python/pydser/.venv/lib/python3.10/site-packages/sqlalchemy/util/compat.py", line 207, in raise_
    raise exception
  File "/home/kido/projects/test/python/pydser/.venv/lib/python3.10/site-packages/sqlalchemy/orm/state.py", line 477, in _initialize_instance
    return manager.original_init(*mixed[1:], **kwargs)
  File "/home/kido/projects/test/python/pydser/.venv/lib/python3.10/site-packages/sqlmodel/main.py", line 518, in __init__
    setattr(__pydantic_self__, key, data[key])
  File "/home/kido/projects/test/python/pydser/.venv/lib/python3.10/site-packages/sqlmodel/main.py", line 528, in __setattr__
    set_attribute(self, name, value)
  File "/home/kido/projects/test/python/pydser/.venv/lib/python3.10/site-packages/sqlalchemy/orm/attributes.py", line 2255, in set_attribute
    state.manager[key].impl.set(state, dict_, value, initiator)
  File "/home/kido/projects/test/python/pydser/.venv/lib/python3.10/site-packages/sqlalchemy/orm/attributes.py", line 1602, in set
    collections.bulk_replace(
  File "/home/kido/projects/test/python/pydser/.venv/lib/python3.10/site-packages/sqlalchemy/orm/collections.py", line 843, in bulk_replace
    appender(member, _sa_initiator=initiator)
  File "/home/kido/projects/test/python/pydser/.venv/lib/python3.10/site-packages/sqlalchemy/orm/collections.py", line 1169, in append
    item = __set(self, item, _sa_initiator)
  File "/home/kido/projects/test/python/pydser/.venv/lib/python3.10/site-packages/sqlalchemy/orm/collections.py", line 1134, in __set
    item = executor.fire_append_event(item, _sa_initiator)
  File "/home/kido/projects/test/python/pydser/.venv/lib/python3.10/site-packages/sqlalchemy/orm/collections.py", line 753, in fire_append_event
    return self.attr.fire_append_event(
  File "/home/kido/projects/test/python/pydser/.venv/lib/python3.10/site-packages/sqlalchemy/orm/attributes.py", line 1429, in fire_append_event
    value = fn(state, value, initiator or self._append_token)
  File "/home/kido/projects/test/python/pydser/.venv/lib/python3.10/site-packages/sqlalchemy/orm/attributes.py", line 1765, in emit_backref_from_collection_append_event
    child_state, child_dict = instance_state(child), instance_dict(child)
AttributeError: 'dict' object has no attribute '_sa_instance_state'

Metadata

Metadata

Assignees

No one assigned

    Labels

    questionFurther information is requested

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions