[sqlalchemy] Can not access the __table__ attribute in string-based primaryjoin parameter

2010-04-02 Thread Jack
People can use string-based primaryjoin parameter to define the
sqlalchemy.orm.relation instance if people use declarative base
class. But the __table__ attribute is not available. Look at this
example.

Chassis and Blade are sub-class of System.  The sysid property
shares the same name in parent and children classes. And there is one-
to-many relationship between Chassis and Blade. So for example I have
to use Chassis.__table__.c.sysid instead of Chassis.sysid to
define join condition. The error line marked # error happens
# can cause following exception.

I know work-around, like renaming sysid, or using Python clause
instead of string in primaryjoin parameter and defining relation
outside class definition. But I wonder whether it is problem or is by
design. Anyone can help? Thx!

p.s. my sqlalchemy is latest 0.6 (changeset:   6410:09e0ec53d4d0)

##
#exception
##
  File d:\program\src\python\sqlalchemy\lib\sqlalchemy\orm
\mapper.py, line 822, in _get_property
raise sa_exc.InvalidRequestError(Mapper '%s' has no property
'%s' % (str(self), key))
InvalidRequestError: Mapper 'Mapper|Chassis|tbl_chassis' has no
property '__table__'


##
#code
##
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import (Column, ForeignKey, Integer, String)
from sqlalchemy.orm import relation


SYS_TYPE_UNKNOWN = 0
SYS_TYPE_CHASSIS = 1
SYS_TYPE_BLADE = 2

Base = declarative_base()

class System(Base):
'''Generic system'''
__tablename__ = 'tbl_system'
sysid = Column(Integer, primary_key=True, autoincrement=True)
sys_type = Column(Integer)
__mapper_args__ = {'polymorphic_on': sys_type,
'polymorphic_identity': SYS_TYPE_UNKNOWN}


class Chassis(System):
'''BladeCenter Chassis'''
__tablename__ = 'tbl_chassis'
__mapper_args__ = {'polymorphic_identity': SYS_TYPE_CHASSIS}
sysid = Column(Integer, ForeignKey('tbl_system.sysid'),
primary_key=True)

# error happens #
blades = relation('Blade', primaryjoin='Chassis.__table__.c.sysid
== Blade.chassis_sysid', backref='chassis')


class Blade(System):
'''Blade server'''
__tablename__ = 'tbl_blade'
__mapper_args__ = {'polymorphic_identity': SYS_TYPE_BLADE}
sysid = Column(Integer, ForeignKey('tbl_system.sysid'),
primary_key=True)
chassis_sysid = Column(Integer, ForeignKey('tbl_chassis.sysid'))

if __name__ == '__main__':
ch1 = Chassis()

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalch...@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.



Re: [sqlalchemy] Can not access the __table__ attribute in string-based primaryjoin parameter

2010-04-02 Thread Michael Bayer
Jack wrote:
 People can use string-based primaryjoin parameter to define the
 sqlalchemy.orm.relation instance if people use declarative base
 class. But the __table__ attribute is not available. Look at this
 example.

its a limited subset of behaviors which are allowed within the evaluated
strings.  In this case, there is a check to ensure you aren't trying to
use a relationship() or other construct in your string, but it wasn't
prepared for an attribute that isn't mapped at all.  An informative error
message for that has been committed in r6143041d8c4a.

When two tables have the same column you need to name them with different
attributes in order to reference both.   The declarative docs certainly
need an example of this since it is a common use case:

class System(Base):
   ...
   sysid = Column(Integer, primary_key=True, autoincrement=True)
   ...

class Chassis(System):
...
local_sysid = Column(sysid, Integer,
ForeignKey('tbl_system.sysid'),primary_key=True)
blades = relation('Blade',
primaryjoin=Chassis.local_sysid==Blade.chassis_sysid,
backref='chassis')
...


-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalch...@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.