On Fri, Dec 04, 2009 at 02:52:37PM -0500, Michael Bayer wrote:
> 
> On Dec 4, 2009, at 2:20 PM, Alessandro Dentella wrote:
> 
> > On Fri, Dec 04, 2009 at 01:27:46PM -0500, Michael Bayer wrote:
> >> 
> >> On Dec 4, 2009, at 1:18 PM, Alessandro Dentella wrote:
> >> 
> >>>>> Is the only solution to attach an instance (u.job = myjob) or is there
> >>>>> another solution that doesn't require me to build the instance?
> >>>> 
> >>>> if you want SQLA's delete-orphan capability, that's the only way.  If 
> >>>> you want to rely upon CASCADE rules in your DB to handle it instead, 
> >>>> that's another way to go.
> >>> 
> >>> thanks, and really... managing in the db is such a simple thing...
> >>> 
> >>> Is there a why to find out the related class (that one u.job should be
> >>> instance of) so that I can issue a query on that?
> >> 
> >> 
> >> err, given what to start with ?
> > 
> > ops. Let's say starting from the class and the instance.
> > 
> > class Project(Base):
> >     __tablename__ = "project"
> >     id = Column(Integer, primary_key=True)
> >     name               = Column(String(30), nullable=False)
> > 
> > class Delivery(Base):
> >     __tablename__ = 'delivery'
> >     id            = Column(Integer, primary_key=True)
> >     project_id        = Column(ForeignKey(Project.id), nullable=False)
> > 
> >     project = orm.relation('Project', backref=orm.backref('deliveries', 
> > cascade="all, delete-orphan", lazy=False))
> > 
> > 
> > sess = session()
> > p = Project()
> > d = Delivery()
> > d.project_id = p.id
> > 
> > # now I want to create automatically the instance 'p' having just 
> > 
> >  * the value 'p.id'
> >  * d
> >  * the name of the attribute (that is a ForeignKey) project_id
> 
> well what you'd need here is the name "project", pull that attribute off of 
> d's mapper and figure it out from there.    you see this is why SQLA doesn't 
> know what to do with your "d.project_id" and why we don't get into attaching 
> rules to foreign key identifiers.  Its only a target during the flush, and a 
> value inside a SQL expression that is populated during a lazy load.   it 
> could just as well be associated with multiple relations() attached to your 
> Delivery class, and if the mapping is really exotic those relations could 
> even be loading different classes based on the same column attribute - it can 
> be in any number of primaryjoin expressions for example.
> 
> So if you really only had "project_id", and you want to assume its only used 
> in one relation() on d, this is what you'd have to do:
> 
> # get parent mapper
> mapper = object_mapper(d)
> 
> # convert from attribute to actual column
> column = mapper.get_property('project_id').columns[0]
> 
> # search through all properties
> for prop in mapper.iterate_properties:
>     # search through "local=remote" pairs for that prop (usually just one 
> tuple)
>     if hasattr(prop, 'local_remote_pairs'):
>         for local, remote in prop.local_remote_pairs:
>             if local is column:
>                 result = remote
>                 break
>         else:
>             result = None
> 
>         if result is not None:
>             target_class = prop.mapper.class_
>             # get the attribute name for the remote column.   usually this
>             # is column.key, but this is a more "complete" check in case
>             # columns have been custom mapped.   
>             attr_name = prop.mapper._get_col_to_prop(result).key
>             break
> else:
>     target_class = attr_name = None
> 
> if target_class:
>     sess.query(target_class).filter_by(**{attr_name:d.project_id})
> 


thanks. That's pretty clear and I could translate it also for the simpler
case when I have 'project'.

sandro
*:-)

--

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