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.