Simon, your idea about putting together a script is a good one. Please see the attached. I think all these errors are related but I'm scratching my head about what the problem is.
The reason I use self.creator[0] versus self.creator is for aesthetics. And, to your point about creator not being a list, SQLAlchemy is treating creator as a list-like object. Since any company can only have one creator, I wasn't concerned about indexing creator[0]. >>> a=session.query(Company).first() >>> a Company1, created by mike rather than >>> a=session.query(Company).first() >>> a Company1, created by [mike] >>> a.creator [mike] More info on creator: >>> type(a.creator) <class 'sqlalchemy.orm.collections.InstrumentedList'> >>> type(a.creator[0]) <class '__main__.Creator'> Chris On Wednesday, August 14, 2013 6:18:51 AM UTC-4, Simon King wrote: > > I think you may be confused about the relationship properties you have > here. As far as I can tell, a Creator can have many companies, but > each Company has only one creator, correct? So Company.creator should > only ever be an instance of Creator (or None), whereas > Creator.companies should be a list. > > In your __repr__ example: > > class Creator(Base): > def __repr__(self): > return '%s' % self.creator > > class Company(Base): > def __repr__(self): > return '%s, created by %s' % (self.company, self.creator[0]) > > Why are you using "self.creator[0]" here? self.creator is not a list, > it should either be an instance of Creator, or None. > > Overriding __repr__ is also a good way to make debugging difficult. > For example, if you had a list of Creator instances and you printed > them at the python prompt, it would just look like a list of strings. > When I want extra information from __repr__, I normally write it > something like this: > > def __repr__(self): > classname = type(self).__name__ > return '<%s name=%r>' % (classname, self.name) > > In your second example: > > >>> a=session.query(Creator).first() > >>> a[0].companies > >>> a.companies > > Query.first() returns a single value, not a list. So typing "a[0]" > doesn't make any sense. > > Please try to create a self-contained script that demonstrates your > problem. Here is a good example: > > https://groups.google.com/d/msg/sqlalchemy/jQtIRJXVfH8/LgwX-bomEIQJ > > Thanks, > > Simon > > On Wed, Aug 14, 2013 at 2:45 AM, <csd...@gmail.com <javascript:>> wrote: > > I'm afraid there are still some bugs in here that hopefully you can help > > with. > > > > class Creator(Base): > > __tablename__ = "creators" > > id = Column(Integer, primary_key = True) > > company_id = Column(Integer, ForeignKey('companies.id')) > > creator = Column(String(100), nullable=False, unique=True) > > def __init__(self, creator): > > self.creator = creator > > def __repr__(self): > > return '%s' % self.creator # otherwise returns a single entry > list > > for some reason (e.g. would display [user]) > > > > class Company(Base): > > __tablename__ = "companies" > > id = Column(Integer, primary_key = True) > > company = Column(String(100), unique=True, nullable=False) #might > want > > to revise string sizes at some point > > creator = relationship("Creator", backref="companies", > cascade="all") > > def __init__(self, company, creator): > > self.company = company > > #self.creator.append(Creator(creator)) > > existing_creator = > > session.query(Creator).filter_by(creator=creator).first() > > #self.creator.append(existing_creator or Creator(creator)) > > if existing_creator: > > print True > > self.creator.append(existing_creator) > > else: > > self.creator.append(Creator(creator)) > > def __repr__(self): > > return '%s, created by %s' % (self.company, self.creator[0]) > > > > > > > > 1) Weird __repr__ error: > > > > class Creator(Base): > > def __repr__(self): > > return '%s' % self.creator > > > > class Company(Base): > > def __repr__(self): > > return '%s, created by %s' % (self.company, self.creator[0]) > > > >>>> c=Company("Company1", "mike") > >>>> session.add(c) > >>>> c=Company("Company2", "mike") > > True > >>>> session.add(c) > >>>> c=Company("Company3", "john") > >>>> session.add(c) > >>>> c=Company("Company4", "mike") > > True > >>>> session.add(c) > >>>> session.query(Company).all() > > [Traceback (most recent call last): > > File "<stdin>", line 1, in <module> > > File "<stdin>", line 17, in __repr__ > > > > > > However, if I divide the query lines among every add() statement, there > is > > no __repr__ error. > > > >>>> c=Company("Company1", "mike") > >>>> session.add(c) > >>>> session.query(Company).all() > > [Company1, created by mike] > >>>> c=Company("Company2", "mike") > > True > >>>> session.add(c) > >>>> session.query(Company).all() > > [Company1, created by mike, Company2, created by mike] > >>>> c=Company("Company3", "john") > >>>> session.add(c) > >>>> session.query(Company).all() > > [Company1, created by mike, Company2, created by mike, Company3, created > by > > john] > >>>> c=Company("Company4", "mike") > > True > >>>> session.add(c) > >>>> session.query(Company).all() > > [Company1, created by mike, Company2, created by mike, Company3, created > by > > john, Company4, created by mike] > > > > > > 2) Creator.companies only shows the most recently added company: > > > >>>> session.query(Company).all() > > [Company1, created by mike, Company2, created by mike, Company3, created > by > > john, Company4, created by mike] > >>>> session.query(Creator).all() > > [mike, john] > >>>> a=session.query(Creator).first() > >>>> a[0].companies > >>>> a.companies > > Company4, created by mike > > > > > > 3) Weird Company.creator error: > > > >>>> session.query(Company).all() > > [Company1, created by mike, Company2, created by mike, Company3, created > by > > john, Company4, created by mike] > >>>> session.query(Company.creator).all() > > [(False,), (False,), (False,), (False,), (True,), (False,), (False,), > > (True,)] > >>>> a=session.query(Company).first() > >>>> a.creator > > [mike] > > > > Anyone have any ideas? > > > > -- > > You received this message because you are subscribed to the Google > Groups > > "sqlalchemy" group. > > To unsubscribe from this group and stop receiving emails from it, send > an > > email to sqlalchemy+...@googlegroups.com <javascript:>. > > To post to this group, send email to > > sqlal...@googlegroups.com<javascript:>. > > > Visit this group at http://groups.google.com/group/sqlalchemy. > > For more options, visit https://groups.google.com/groups/opt_out. > > > > > -- You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To unsubscribe from this group and stop receiving emails from it, send an email to sqlalchemy+unsubscr...@googlegroups.com. To post to this group, send email to sqlalchemy@googlegroups.com. Visit this group at http://groups.google.com/group/sqlalchemy. For more options, visit https://groups.google.com/groups/opt_out.
from sqlalchemy import * from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import relationship, backref from sqlalchemy.orm import sessionmaker engine = create_engine('mysql://project:project@localhost/cbff', echo=False) # Toggle echo to show db interactions Base = declarative_base() Session = sessionmaker(bind=engine) session = Session() class Creator(Base): __tablename__ = "creators" id = Column(Integer, primary_key = True) company_id = Column(Integer, ForeignKey('companies.id')) creator = Column(String(100), nullable=False, unique=True) def __init__(self, creator): self.creator = creator def __repr__(self): return '%s' % self.creator class Company(Base): __tablename__ = "companies" id = Column(Integer, primary_key = True) company = Column(String(100), unique=True, nullable=False) creator = relationship("Creator", backref="companies", cascade="all") def __init__(self, company, creator): self.company = company existing_creator = session.query(Creator).filter_by(creator=creator).first() if existing_creator: self.creator.append(existing_creator) else: self.creator.append(Creator(creator)) def __repr__(self): return '%s, created by %s' % (self.company, self.creator) Base.metadata.create_all(engine) print""" Bug #1 Session.query() affects __repr__ for some reason. ------ """ # Output: # Case #1 # >>> c=Company("Company1", "mike") # >>> session.add(c) # >>> c=Company("Company2", "mike") # >>> session.add(c) # >>> c=Company("Company3", "john") # >>> session.add(c) # >>> c=Company("Company4", "mike") # >>> session.add(c) # >>> session.query(Company).all() # [Company1, created by [], Company2, created by [], Company3, created by [john], Company4, created by [mike]] # Case #2 # >>> c=Company("Company1", "mike") # >>> session.add(c) # >>> session.query(Company).all() # [Company1, created by [mike]] # >>> c=Company("Company2", "mike") # >>> session.add(c) # >>> session.query(Company).all() # [Company1, created by [mike], Company2, created by [mike]] # >>> c=Company("Company3", "john") # >>> session.add(c) # >>> session.query(Company).all() # [Company1, created by [mike], Company2, created by [mike], Company3, created by [john]] # >>> c=Company("Company4", "mike") # >>> session.add(c) # >>> session.query(Company).all() # [Company1, created by [mike], Company2, created by [mike], Company3, created by [john], Company4, created by [mike]] print "Case #1" c=Company("Company1", "mike") session.add(c) c=Company("Company2", "mike") session.add(c) c=Company("Company3", "john") session.add(c) c=Company("Company4", "mike") session.add(c) session.query(Company).all() session.rollback() print "Case #2" c=Company("Company1", "mike") session.add(c) session.query(Company).all() c=Company("Company2", "mike") session.add(c) session.query(Company).all() c=Company("Company3", "john") session.add(c) session.query(Company).all() c=Company("Company4", "mike") session.add(c) session.query(Company).all() print""" Bug #2 Creator.companies only shows the most recently added company, when it should return a list of all companies linked to a particular creator """ # Output: # >>> session.query(Company).all() # [Company1, created by mike, Company2, created by mike, Company3, created by john, Company4, created by mike] # >>> session.query(Creator).all() # [mike, john] # >>> a=session.query(Creator).first() # >>> a.companies # Company4, created by mike session.query(Company).all() session.query(Creator).all() a=session.query(Creator).first() a.companies print """ Bug #3 Immediately after the above, doing session.query(Company.all() again throws an error message. NOTE: I tried to replicate this error after putting this script together and couldn't reproduce it. I do not know why this is. """ # Output: # >>> session.query(Company).all() # [Traceback (most recent call last): # File "<stdin>", line 1, in <module> # File "<stdin>", line 14, in __repr__ # IndexError: list index out of range session.query(Company).all() print """ Bug #4 The above errors seems to be linked to the following odd behavior """ # Output: # >>> session.query(Company.creator).all() # [(False,), (False,), (False,), (False,), (True,), (False,), (False,), (True,)] session.query(Company.creator).all()