Skip to content

User Guide Example throws AttributeError #345

@mkrd

Description

@mkrd

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


class Team(SQLModel, table=True):
    id: Optional[int] = Field(default=None, primary_key=True)
    name: str = Field(index=True)
    headquarters: str

    heroes: List["Hero"] = Relationship(back_populates="team")


class Hero(SQLModel, table=True):
    id: Optional[int] = Field(default=None, primary_key=True)
    name: str = Field(index=True)
    secret_name: str
    age: Optional[int] = Field(default=None, index=True)

    team_id: Optional[int] = Field(default=None, foreign_key="team.id")
    team: Optional[Team] = Relationship(back_populates="heroes")


sqlite_file_name = "database.db"
sqlite_url = f"sqlite:///{sqlite_file_name}"

engine = create_engine(sqlite_url, echo=True)


def create_db_and_tables():
    SQLModel.metadata.create_all(engine)


def create_heroes():
    with Session(engine) as session:
        team_preventers = Team(name="Preventers", headquarters="Sharp Tower")
        team_z_force = Team(name="Z-Force", headquarters="Sister Margaret’s Bar")

        hero_deadpond = Hero(
            name="Deadpond", secret_name="Dive Wilson", team=team_z_force
        )
        hero_rusty_man = Hero(
            name="Rusty-Man", secret_name="Tommy Sharp", age=48, team=team_preventers
        )
        hero_spider_boy = Hero(name="Spider-Boy", secret_name="Pedro Parqueador")
        session.add(hero_deadpond)
        session.add(hero_rusty_man)
        session.add(hero_spider_boy)
        session.commit()

        session.refresh(hero_deadpond)
        session.refresh(hero_rusty_man)
        session.refresh(hero_spider_boy)

        print("Created hero:", hero_deadpond)
        print("Created hero:", hero_rusty_man)
        print("Created hero:", hero_spider_boy)

        hero_spider_boy.team = team_preventers
        session.add(hero_spider_boy)
        session.commit()
        session.refresh(hero_spider_boy)
        print("Updated hero:", hero_spider_boy)

        hero_black_lion = Hero(name="Black Lion", secret_name="Trevor Challa", age=35)
        hero_sure_e = Hero(name="Princess Sure-E", secret_name="Sure-E")
        team_wakaland = Team(
            name="Wakaland",
            headquarters="Wakaland Capital City",
            heroes=[hero_black_lion, hero_sure_e],
        )
        session.add(team_wakaland)
        session.commit()
        session.refresh(team_wakaland)
        print("Team Wakaland:", team_wakaland)

        hero_tarantula = Hero(name="Tarantula", secret_name="Natalia Roman-on", age=32)
        hero_dr_weird = Hero(name="Dr. Weird", secret_name="Steve Weird", age=36)
        hero_cap = Hero(
            name="Captain North America", secret_name="Esteban Rogelios", age=93
        )

        team_preventers.heroes.append(hero_tarantula)
        team_preventers.heroes.append(hero_dr_weird)
        team_preventers.heroes.append(hero_cap)
        session.add(team_preventers)
        session.commit()
        session.refresh(hero_tarantula)
        session.refresh(hero_dr_weird)
        session.refresh(hero_cap)
        print("Preventers new hero:", hero_tarantula)
        print("Preventers new hero:", hero_dr_weird)
        print("Preventers new hero:", hero_cap)


def main():
    create_db_and_tables()
    create_heroes()


if __name__ == "__main__":
    main()

Description

Official Code Example from https://sqlmodel.tiangolo.com/tutorial/relationship-attributes/create-and-update-relationships/#include-relationship-objects-in-the-many-side

Running the code as instructed throws an AttributeError:

2022-05-19 10:57:57,546 INFO sqlalchemy.engine.Engine BEGIN (implicit)
2022-05-19 10:57:57,546 INFO sqlalchemy.engine.Engine PRAGMA main.table_info("team")
2022-05-19 10:57:57,546 INFO sqlalchemy.engine.Engine [raw sql] ()
2022-05-19 10:57:57,547 INFO sqlalchemy.engine.Engine PRAGMA main.table_info("hero")
2022-05-19 10:57:57,547 INFO sqlalchemy.engine.Engine [raw sql] ()
2022-05-19 10:57:57,547 INFO sqlalchemy.engine.Engine COMMIT
2022-05-19 10:57:57,547 INFO sqlalchemy.engine.Engine BEGIN (implicit)
2022-05-19 10:57:57,548 INFO sqlalchemy.engine.Engine INSERT INTO hero (name, secret_name, age, team_id) VALUES (?, ?, ?, ?)
2022-05-19 10:57:57,548 INFO sqlalchemy.engine.Engine [generated in 0.00006s] ('Deadpond', 'Dive Wilson', None, None)
2022-05-19 10:57:57,548 INFO sqlalchemy.engine.Engine INSERT INTO hero (name, secret_name, age, team_id) VALUES (?, ?, ?, ?)
2022-05-19 10:57:57,548 INFO sqlalchemy.engine.Engine [cached since 0.0004535s ago] ('Rusty-Man', 'Tommy Sharp', 48, None)
2022-05-19 10:57:57,549 INFO sqlalchemy.engine.Engine INSERT INTO hero (name, secret_name, age, team_id) VALUES (?, ?, ?, ?)
2022-05-19 10:57:57,549 INFO sqlalchemy.engine.Engine [cached since 0.0005178s ago] ('Spider-Boy', 'Pedro Parqueador', None, None)
2022-05-19 10:57:57,549 INFO sqlalchemy.engine.Engine COMMIT
2022-05-19 10:57:57,550 INFO sqlalchemy.engine.Engine BEGIN (implicit)
2022-05-19 10:57:57,551 INFO sqlalchemy.engine.Engine SELECT hero.id, hero.name, hero.secret_name, hero.age, hero.team_id 
FROM hero 
WHERE hero.id = ?
2022-05-19 10:57:57,551 INFO sqlalchemy.engine.Engine [generated in 0.00007s] (7,)
2022-05-19 10:57:57,551 INFO sqlalchemy.engine.Engine SELECT hero.id, hero.name, hero.secret_name, hero.age, hero.team_id 
FROM hero 
WHERE hero.id = ?
2022-05-19 10:57:57,551 INFO sqlalchemy.engine.Engine [cached since 0.0005488s ago] (8,)
2022-05-19 10:57:57,551 INFO sqlalchemy.engine.Engine SELECT hero.id, hero.name, hero.secret_name, hero.age, hero.team_id 
FROM hero 
WHERE hero.id = ?
2022-05-19 10:57:57,551 INFO sqlalchemy.engine.Engine [cached since 0.0007544s ago] (9,)
Created hero: name='Deadpond' team_id=None secret_name='Dive Wilson' id=7 age=None
Created hero: name='Rusty-Man' team_id=None secret_name='Tommy Sharp' id=8 age=48
Created hero: name='Spider-Boy' team_id=None secret_name='Pedro Parqueador' id=9 age=None
2022-05-19 10:57:57,551 INFO sqlalchemy.engine.Engine COMMIT
2022-05-19 10:57:57,552 INFO sqlalchemy.engine.Engine BEGIN (implicit)
2022-05-19 10:57:57,552 INFO sqlalchemy.engine.Engine SELECT hero.id, hero.name, hero.secret_name, hero.age, hero.team_id 
FROM hero 
WHERE hero.id = ?
2022-05-19 10:57:57,552 INFO sqlalchemy.engine.Engine [cached since 0.001206s ago] (9,)
Updated hero: name='Spider-Boy' team_id=None secret_name='Pedro Parqueador' id=9 age=None
2022-05-19 10:57:57,552 INFO sqlalchemy.engine.Engine INSERT INTO team (name, headquarters) VALUES (?, ?)
2022-05-19 10:57:57,552 INFO sqlalchemy.engine.Engine [generated in 0.00006s] ('Wakaland', 'Wakaland Capital City')
2022-05-19 10:57:57,553 INFO sqlalchemy.engine.Engine COMMIT
2022-05-19 10:57:57,553 INFO sqlalchemy.engine.Engine BEGIN (implicit)
2022-05-19 10:57:57,554 INFO sqlalchemy.engine.Engine SELECT team.id, team.name, team.headquarters 
FROM team 
WHERE team.id = ?
2022-05-19 10:57:57,554 INFO sqlalchemy.engine.Engine [generated in 0.00006s] (3,)
Team Wakaland: name='Wakaland' headquarters='Wakaland Capital City' id=3
2022-05-19 10:57:57,554 INFO sqlalchemy.engine.Engine ROLLBACK
Traceback (most recent call last):
  File "/Users/marcel/test_sqlmodel/test.py", line 104, in <module>
    main()
  File "/Users/marcel/test_sqlmodel/test.py", line 98, in main
    create_heroes()
  File "/Users/marcel/test_sqlmodel/test.py", line 83, in create_heroes
    team_preventers.heroes.append(hero_tarantula)
AttributeError: 'Team' object has no attribute 'heroes'

Operating System

macOS

Operating System Details

No response

SQLModel Version

0.0.6

Python Version

3.10.4

Additional Context

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    answeredquestionFurther information is requested

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions