[sqlalchemy] Re: Is multi-level polymorphism possible in SQLAlchemy?

2010-05-20 Thread Kiran Jonnalagadda
On May 19, 9:52 pm, Kiran Jonnalagadda j...@pobox.com wrote:
 class Note(Entity):
     __tablename__ = 'notes'
     __mapper_args__ = {'polymorphic_identity': u'note',
                        'inherit_condition': (id == Entity.id)}
     id = Column(Integer, ForeignKey('entities.id'), primary_key=True)

There's my problem. __mapper_args__ is referring to id before it is
defined. Swapping the order fixed it.

-- 
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.



[sqlalchemy] Re: Is multi-level polymorphism possible in SQLAlchemy?

2010-05-19 Thread Kiran Jonnalagadda
Thanks. I've got this working now, but am having trouble combining
polymorphism and multiple foreign keys to the same table. Here's
roughly what I'm doing:

class Entity(Base):
__tablename__ = 'entities'
id = Column(Integer, primary_key=True)
# ...bunch of columns...
type = Column(Unicode(20), nullable=False)
__mapper_args__ = {'polymorphic_on': type}

class Site(Entity): # Client account
__tablename__ = 'sites'
__mapper_args__ = {'polymorphic_identity': u'site'}
id = Column(Integer, ForeignKey('entities.id'), primary_key=True)
name = Column(Unicode(50), unique=True, nullable=False)
title = Column(Unicode(50), nullable=False)

# ...few more Entity derived models...

class Note(Entity):
__tablename__ = 'notes'
__mapper_args__ = {'polymorphic_identity': u'note',
   'inherit_condition': (id == Entity.id)}
id = Column(Integer, ForeignKey('entities.id'), primary_key=True)
site_id = Column(Integer, ForeignKey('deals.id'), nullable=False)
site = relation(Site, foreign_keys=site_id,
primaryjoin=site_id == Site.id)
attached_to_id = Column(Integer, ForeignKey('entities.id'),
nullable=False)
attached_to = relation(Entity, foreign_keys=attached_to_id,
   primaryjoin=attached_to_id == Entity.id,
backref=backref('notes', cascade='all, delete-
orphan'))
note = Column(Unicode(255), nullable=False)

I use Note.site to determine access rights and Note.attached_to to
determine containment. This declaration works until I try to delete a
site instance. SQLAlchemy throws up this exception:

...
File /usr/local/lib/python2.6/dist-packages/sqlalchemy/sql/
compiler.py, line 287, in construct_params
pd[self.bind_names[bindparam]] = bindparam.value()
TypeError: id() takes exactly one argument (0 given)

However, if I remove the backref on attached_to, everything works
fine. If I move the backref to Note.site, it fails with the same
error. If I remove attached_to* and keep the backref on site, it works
again. I'm not sure what's wrong.

Here's the full traceback, for reference.

Traceback (most recent call last):
  File /home/jace/Projects/saproj/tests.py, line 76, in test_cascade
self.session.delete(site)
  File /usr/local/lib/python2.6/dist-packages/sqlalchemy/orm/
session.py, line 1088, in delete
cascade_states = list(_cascade_state_iterator('delete', state))
  File /usr/local/lib/python2.6/dist-packages/sqlalchemy/orm/
session.py, line 1534, in _cascade_state_iterator
for (o, m) in mapper.cascade_iterator(cascade, state, **kwargs):
  File /usr/local/lib/python2.6/dist-packages/sqlalchemy/orm/
mapper.py, line 1229, in cascade_iterator
instance, instance_mapper, corresponding_state  = iterator.next()
  File /usr/local/lib/python2.6/dist-packages/sqlalchemy/orm/
properties.py, line 703, in cascade_iterator
instances = state.value_as_iterable(self.key, passive=passive)
  File /usr/local/lib/python2.6/dist-packages/sqlalchemy/orm/
state.py, line 128, in value_as_iterable
x = impl.get(self, dict_, passive=passive)
  File /usr/local/lib/python2.6/dist-packages/sqlalchemy/orm/
attributes.py, line 377, in get
value = callable_(passive=passive)
  File /usr/local/lib/python2.6/dist-packages/sqlalchemy/orm/
strategies.py, line 563, in __call__
result = q.all()
  File /usr/local/lib/python2.6/dist-packages/sqlalchemy/orm/
query.py, line 1286, in all
return list(self)
  File /usr/local/lib/python2.6/dist-packages/sqlalchemy/orm/
query.py, line 1394, in __iter__
return self._execute_and_instances(context)
  File /usr/local/lib/python2.6/dist-packages/sqlalchemy/orm/
query.py, line 1399, in _execute_and_instances
mapper=self._mapper_zero_or_none())
  File /usr/local/lib/python2.6/dist-packages/sqlalchemy/orm/
session.py, line 737, in execute
clause, params or {})
  File /usr/local/lib/python2.6/dist-packages/sqlalchemy/engine/
base.py, line 1086, in execute
return Connection.executors[c](self, object, multiparams, params)
  File /usr/local/lib/python2.6/dist-packages/sqlalchemy/engine/
base.py, line 1149, in _execute_clauseelement
parameters=params
  File /usr/local/lib/python2.6/dist-packages/sqlalchemy/engine/
base.py, line 1237, in __create_execution_context
return dialect.execution_ctx_cls(dialect, connection=self,
**kwargs)
  File /usr/local/lib/python2.6/dist-packages/sqlalchemy/engine/
default.py, line 355, in __init__
grp,m in enumerate(parameters)]
  File /usr/local/lib/python2.6/dist-packages/sqlalchemy/sql/
compiler.py, line 287, in construct_params
pd[self.bind_names[bindparam]] = bindparam.value()
TypeError: id() takes exactly one argument (0 given)

Thanks for the help.


On May 18, 10:42 pm, Michael Bayer mike...@zzzcomputing.com wrote:
 Don't use None for the Column type (i.e., detected as the null type).  Put 
 the type explicitly.   This has been updated in the documentation recently 
 since the None 

[sqlalchemy] Re: Is multi-level polymorphism possible in SQLAlchemy?

2010-05-18 Thread Michael Bayer
Don't use None for the Column type (i.e., detected as the null type).  Put 
the type explicitly.   This has been updated in the documentation recently 
since the None feature can't be fully supported at this time.


On May 18, 2010, at 1:34 PM, Kiran Jonnalagadda wrote:

 Is it possible to have multi-level polymorphism in SQLAlchemy? Here's
 an example:
 
 class Entity(Base):
__tablename__ = 'entities'
id = Column(Integer, primary_key=True)
created_at = Column(DateTime, default=datetime.utcnow,
 nullable=False)
entity_type = Column(Unicode(20), nullable=False)
__mapper_args__ = {'polymorphic_on': entity_type}
 
 class File(Entity):
__tablename__ = 'files'
id = Column(None, ForeignKey('entities.id'), primary_key=True)
filepath = Column(Unicode(255), nullable=False)
file_type = Column(Unicode(20), nullable=False)
__mapper_args__ = {'polymorphic_identity': u'file',
 'polymorphic_on': file_type)
 
 class Image(File):
__mapper_args__ = {'polymorphic_identity': u'image'}
__tablename__ = 'images'
id = Column(None, ForeignKey('files.id'), primary_key=True)
width = Column(Integer)
height = Column(Integer)
 
 When I call Base.metadata.create_all(), SQLAlchemy raises the
 following error: NotImplementedError: Can't generate DDL for the null
 type. This error goes away if I remove the Image model.
 
 What gives?
 
 I sense that declaring both polymorphic_identity and polymorphic_on in
 File isn't doing the expected thing, but I'm not sure how else to do
 this.

-- 
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.