sqlalchemy.orm.exc.UnmappedInstanceError: Class 'builtins.NoneType' is not mapped

20,724

In Python methods that mutate an object in-place usually return None. Your assignment's expression chains creating the model object, accessing a relationship attribute, and appending to said attribute, which returns None. Split the operations:

user1 = User(
    username="Stephen",
    password_hash="p-hash",
    email="[email protected]"
)

task1 = Task(
    title='Delete Me',
    folder_name='Folder 1'
)

task1.subtasks.append(
    Subtask(
        title='Delete Me 2'
    )
)

user1.tasks.append(task1)
Share:
20,724
Stephen Collins
Author by

Stephen Collins

Updated on July 09, 2022

Comments

  • Stephen Collins
    Stephen Collins almost 2 years

    I have 3 sqlalchemy models setup which are all one to many relationships. The User model contains many Task models and the Task model contains many Subtask models. When I execute the test_script.py I get the error sqlalchemy.orm.exc.UnmappedInstanceError: Class 'builtins.NoneType' is not mapped.

    I have read and tried a few different relationships on each module. My goal is to be able to have lists in the User and Task models containing their correct children. I would eventually like to access list items such as user_x.task[3].subtask[1]

    Here is the code, (models, script, error)

    models

    class User(Base):
        """ User Model for storing user related details """
        __tablename__ = 'Users'
    
        id = Column(Integer, primary_key=True, autoincrement=True, nullable=False)
        username = Column(String(255), nullable=False)
        password_hash = Column(String(128), nullable=False)
        email = Column(String(255), nullable=False, unique=True)
        created_date = Column(DateTime, default=datetime.utcnow)
    
        tasks = relationship(Task, backref=backref("Users", uselist=False))
    
        def __init__(self, username: str, password_hash: str, email: str):
            self.username = username
            self.password_hash = password_hash
            self.email = email
    
    
    
    class Task(Base):
        """ Task Model for storing task related details """
        __tablename__ = 'Tasks'
    
        id = Column(Integer, primary_key=True, autoincrement=True, nullable=False)
        title = Column(String(255), nullable=False)
        folder_name = Column(String(255), nullable=True)
        due_date = Column(DateTime, nullable=True)
        starred = Column(Boolean, default=False)
        completed = Column(Boolean, default=False)
        note = Column(String, nullable=True)
        created_date = Column(DateTime, default=datetime.utcnow)
        user_id = Column(Integer, ForeignKey('Users.id'))
    
        subtasks = relationship(Subtask, backref=backref("Tasks", uselist=False))
    
        def __init__(self, title: str, **kwargs):
            self.title = title
            self.folder_name = kwargs.get('folder_name', None)
            self.due_date = kwargs.get('due_date', None)
            self.starred = kwargs.get('starred', False)
            self.completed = kwargs.get('completed', False)
            self.note = kwargs.get('note', None)
    
    
    
    class Subtask(Base):
        """ Subtask Model for storing subtask related details """
        __tablename__ = 'Subtasks'
    
        id = Column(Integer, primary_key=True, nullable=False, autoincrement=True)
        title = Column(String(255), nullable=False)
        completed = Column(Boolean, default=False)
        task_id = Column(Integer, ForeignKey('Tasks.id'))
    
        def __init__(self, title: str, **kwargs):
            self.title = title
            self.completed = kwargs.get('completed', False)
    

    test_script.py

    session1 = create_session()
    
    user1 = User(
        username="Stephen",
        password_hash="p-hash",
        email="[email protected]"
    ).tasks.append(
        Task(
            title='Delete Me',
            folder_name='Folder 1'
        ).subtasks.append(
            Subtask(
                title='Delete Me 2'
            )
        )
    )
    
    session1.add(user1)
    
    session1.commit()
    session1.close()
    

    error message

    /Users/StephenCollins/Respositories/pycharm_workspace/Personal/BusyAPI_v1/venv/bin/python /Users/StephenCollins/Respositories/pycharm_workspace/Personal/BusyAPI_v1/tests/test_script.py
    Traceback (most recent call last):
      File "/Users/StephenCollins/Respositories/pycharm_workspace/Personal/BusyAPI_v1/venv/lib/python3.7/site-packages/sqlalchemy/orm/session.py", line 1943, in add
        state = attributes.instance_state(instance)
    AttributeError: 'NoneType' object has no attribute '_sa_instance_state'
    
    During handling of the above exception, another exception occurred:
    
    Traceback (most recent call last):
      File "/Users/StephenCollins/Respositories/pycharm_workspace/Personal/BusyAPI_v1/tests/test_script.py", line 24, in <module>
        session1.add(user1)
      File "/Users/StephenCollins/Respositories/pycharm_workspace/Personal/BusyAPI_v1/venv/lib/python3.7/site-packages/sqlalchemy/orm/session.py", line 1945, in add
        raise exc.UnmappedInstanceError(instance)
    sqlalchemy.orm.exc.UnmappedInstanceError: Class 'builtins.NoneType' is not mapped
    

    Hopefully I am close but if I am completely in the wrong direction just let me know. I used Hibernate a little bit in my prior internship but I am self taught (the best kind of taught) in python, sqlalchemy, and mysql.

  • Stephen Collins
    Stephen Collins almost 5 years
    Ah good catch! That is something I overlooked, however it still doesn't work... Getting the same error.
  • jspcal
    jspcal almost 5 years
    Perhaps try a test without __init__ in any of the models.
  • Stephen Collins
    Stephen Collins almost 5 years
    I have removed uselist and added back_populates. Still no dice. I removed all relations and put tasks = relationship('Task') in user.py and I put subtasks = relationship('Subtask') in task.py.