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()

Reply via email to