On 03/02/2010 16:34, Adam Tauno Williams wrote:
I'm trying to convert a working non-declarative map of a two-entity
table to declarative style, but the join always fails with
"'_TextClause' object has no attribute 'foreign_keys'"

NON-DECLARATIVE STYLE (WORKING)
--------------------------------------------------
engine = create_engine('postgres://[email protected]/OGo', echo=True)
metadata = MetaData()

x1 = Table('job_history', metadata,
     Column('job_history_id', Integer, Sequence('key_generator'),
primary_key=True),
     Column('job_id', Integer),
     Column('actor_id', Integer),
     Column('action', String))

x2 = Table('job_history_info', metadata,
     Column('job_history_info_id', Integer, Sequence('key_generator'),
primary_key=True),
     Column('comment', String),
     Column('job_history_id', Integer,
ForeignKey('job_history.job_history_id')))

x3 = join(x1, x2)

class Action(object):
     pass

mapper(Action, x3)

Session = sessionmaker()
Session.configure(bind=engine)
db = Session()

z = Action()
z.job_id = 1
z.comment = 'TEST TEST TEST'
z.actor_id = 0
z.action = 'test'
db.add(z)

db.commit()


DECLARATIVE STYLE (FAILS)
-----------------------------------------------
engine = create_engine('postgres://[email protected]/OGo', echo=True)

Base = declarative_base()

class x1(Base):
   __tablename__ = 'job_history'
   id       = Column('job_history_id', Integer,
Sequence('key_generator'), primary_key=True)
   task_id  =  Column('job_id', Integer)
   actor_id = Column('actor_id', Integer)
   action   = Column('action', String)

class x2(Base):
   __tablename__ = 'job_history_info'
   _info_id = Column('job_history_info_id', Integer,
Sequence('key_generator'), primary_key=True)
   comment  = Column('comment', String)
#FAILS  _hist_id = Column('job_history_id', Integer,
ForeignKey('job_history.job_history_id'))
#FAILS  _hist_id = Column('job_history_id', Integer,
ForeignKey('x1.id'))
#FAILS  _hist_id = Column('job_history_id', Integer, ForeignKey(x1.id))
# Uncomment any one of the above for the same result.

x3 = join(x1, x2)

class Action(Base):
     """ An OpenGroupare Task History Info entry """
     __table__           = x3

Session = sessionmaker()
Session.configure(bind=engine)
db = Session()

z = Action()
z.job_id = 1
z.comment = 'TEST TEST TEST'
z.actor_id = 0
z.action = 'test'
db.add(z)

db.commit()
------------------------------------------------------

Why does this work in straight mapper code but not work in declarative?
This seems like a 1:1 correspondence.

STACK TRACE
----------------------------------------------------
Traceback (most recent call last):
   File "./dec.py", line 26, in<module>
     x3 = join(x1, x2)
   File
"/usr/lib/python2.6/site-packages/SQLAlchemy-0.5.4p2-py2.6.egg/sqlalchemy/sql/expression.py",
 line 123, in join
     return Join(left, right, onclause, isouter)
   File
"/usr/lib/python2.6/site-packages/SQLAlchemy-0.5.4p2-py2.6.egg/sqlalchemy/sql/expression.py",
 line 2506, in __init__
     self.onclause = self._match_primaries(self.left, self.right)
   File
"/usr/lib/python2.6/site-packages/SQLAlchemy-0.5.4p2-py2.6.egg/sqlalchemy/sql/expression.py",
 line 2552, in _match_primaries
     return sql_util.join_condition(primary, secondary)
   File
"/usr/lib/python2.6/site-packages/SQLAlchemy-0.5.4p2-py2.6.egg/sqlalchemy/sql/util.py",
 line 100, in join_condition
     for fk in b.foreign_keys:
AttributeError: '_TextClause' object has no attribute 'foreign_keys'
awill...@linux-m3mt:~>

I think this should work and means a bit less typing.

Base = declarative_base()

class x1(Base):
  __tablename__ = 'job_history'
  id       = Column(Integer, Sequence('key_generator'), primary_key=True)
  task_id  =  Column(Integer)
  actor_id = Column(Integer)
  action   = Column(String)

class x2(Base):
  __tablename__ = 'job_history_info'
  _info_id = Column(Integer, Sequence('key_generator'), primary_key=True)
  comment  = Column(String)
  _hist_id = Column(Integer, ForeignKey('job_history.id'))

Unless you need explicit names as described here.
http://www.sqlalchemy.org/docs/05/reference/ext/declarative.html

Werner

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

Reply via email to