I am trying to save Commander decks in a database using Python/SQLAlchemy.I designed the database in MySQL using sqldbm and used SQLAlchemy docs to convert it as properly as I could.
The issue is that I continously get an KeyError
when executing the code to commit decks:
Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/myscript.py", line 359, in scrap_mtgtop8 new_deck.commanders.append(card) File "/venv/lib/python3.11/site-packages/sqlalchemy/orm/collections.py", line 1130, in append item = __set(self, item, _sa_initiator, NO_KEY) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/venv/lib/python3.11/site-packages/sqlalchemy/orm/collections.py", line 1095, in __set item = executor.fire_append_event(item, _sa_initiator, key=key) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/venv/lib/python3.11/site-packages/sqlalchemy/orm/collections.py", line 687, in fire_append_event return self.attr.fire_append_event( ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/venv/lib/python3.11/site-packages/sqlalchemy/orm/attributes.py", line 1756, in fire_append_event value = fn(state, value, initiator or self._append_token, key=key) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/venv/lib/python3.11/site-packages/sqlalchemy/orm/attributes.py", line 2207, in emit_backref_from_collection_append_event child_impl = child_state.manager[key].impl ~~~~~~~~~~~~~~~~~~~^^^^^KeyError: 'deck'
I checked every relationship definition to be sure that they pointed in the right direction.Here is part of the database definition:
class Cartes(Base): __tablename__ = "cartes" id = Column(String, primary_key=True) name = Column(String, nullable=False) type = Column(String, nullable=False) mana_value = Column(Integer, nullable=False) color_identity = Column(String, nullable=False) text = Column(String, nullable=False) first_print = Column(String, ForeignKey("sets.code"), nullable=False) legalities = Column(JSON, nullable=False) decks = relationship("DecksCartes", back_populates="carte") as_commander = relationship("DecksCommanders", back_populates="carte")class Decks(Base): __tablename__ = "decks" id = Column(Integer, primary_key=True) tournoi_id = Column(Integer, ForeignKey("tournois.id"), nullable=False) rank = Column(String, nullable=False) player = Column(String, nullable=False) tournoi = relationship("Tournois", back_populates="decks") cartes = relationship("DecksCartes", back_populates="deck") commanders = relationship("DecksCommanders", back_populates="deck")class DecksCartes(Base): __tablename__ = "decks_cartes" carte_id = Column(String, ForeignKey("cartes.id"), primary_key=True) deck_id = Column(Integer, ForeignKey("decks.id"), primary_key=True) carte = relationship("Cartes", back_populates="decks") deck = relationship("Decks", back_populates="cartes")class DecksCommanders(Base): __tablename__ = "decks_commanders" deck_id = Column(Integer, ForeignKey("decks.id"), primary_key=True) carte_id = Column(String, ForeignKey("cartes.id"), primary_key=True) deck = relationship("Decks", back_populates="commanders") carte = relationship("Cartes", back_populates="as_commander")
The error is raised on the line new_deck.commanders.append(card)
:
deck_data = {"id": deck["id"],"tournoi_id": tournament.tournoi_id,"rank": deck["rank"],"player": deck["player"],}new_deck = Decks(**deck_data)for card_name in deck["commander"]: card = session.query(Cartes).filter_by(name=card_name).first() new_deck.commanders.append(card)for line in deck["decklist"]: qty, card_name = line.split(" ", maxsplit=1) card = session.query(Cartes).filter_by(name=card_name).first() if card: for _ in range(int(qty)): new_deck.cartes.append(card)session.add(new_deck)