执行modify()方法后调用listview()触发TypeError: 'NameCard' object is not iterable异常的原因解析
Alright, let's break down why you're hitting that TypeError and how to fix it.
Root Cause of the Error
The problem boils down to you accidentally overwriting the self.cards attribute of your Handler instance from an iterable SQLAlchemy Query object to a single NameCard instance. Here's the step-by-step breakdown:
When you initialize a
Handler,self.cardsis set toself.session.query(NameCard)— this is aQueryobject, which acts like an iterable collection. That's why yourlistview()method can loop over it withenumerate()without issues initially.But when you run
modify()and select option 1 (edit name), you execute this line:self.cards = self.session.query(NameCard).filter(NameCard.IG==user).one()The
.one()method returns a singleNameCardobject, not a collection of results. At this point,self.cardsis no longer the iterable query you started with — it's just a single instance that can't be looped over.Later, when you call
listview(), it tries to runenumerate(self.cards). Since a singleNameCardisn't an iterable type, Python throws theTypeError: 'NameCard' object is not iterableexception you're seeing.
As for why the change persists after restarting: SQLAlchemy's Session typically commits pending changes when the program exits (or when the Session is garbage collected), so your edit does get saved to the database. The issue only affects the current running instance of your program because self.cards was corrupted.
Simple Fix
The solution is straightforward: don't overwrite self.cards with a single object. Use temporary variables for filtered queries and individual records instead, and make sure you explicitly commit changes to the database:
def modify(self): user = input("The IG of the person you are looking for : ") # Use a temp variable for filtered results instead of overwriting self.cards filtered_cards = self.session.query(NameCard).filter(NameCard.IG==user) cards_counting = filtered_cards.count() if cards_counting == 0: print("ERROR : Not Found") else: for card in filtered_cards: print("Edit the information >>> ",card," <<< Edit the information ") m = int(input("name edit(1) age edit(2) IG edit(3) team edit(4) : ")) if m == 1: new = input("Enter the new name : ") # Use a temp variable for the single target card target_card = filtered_cards.one() target_card.name = new self.session.commit() # Explicitly commit the change to the database # Fetch updated data to confirm the change updated_cards = self.session.query(NameCard).filter(NameCard.IG==user) for new_card in updated_cards: print("###UPDATE Complete >>> ",new_card) # Reset self.cards back to the full collection query for future listview calls self.cards = self.session.query(NameCard)
Extra Tips
- Always use
self.session.commit()after making changes to ensure they're saved immediately, not just when the program ends. - Keep
self.cardsas the full collection query solistview()always pulls the latest data from the database.
内容的提问来源于stack exchange,提问作者이재하

